Tutorial Dynamic Multi Channel Websites

Published on January 2017 | Categories: Documents | Downloads: 27 | Comments: 0 | Views: 141
of 27
Download PDF   Embed   Report

Comments

Content

bemoko tutorial series

April 2010

Purpose of this document

2

Copyright © 2010 bemoko. All rights reserved. No part of this document may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without the prior permission of bemoko. Protected trademarks, brand names etc. of other companies are not explicitly stated as such in the text. The lack of such identifiers in no way implies that the terms are not free names as defined by applicable trade mark and brand name legislation. When given, names of people and companies used as examples are always fictitious.

The information in this document has been carefully checked and can be considered reliable. Nevertheless, no guarantee can be given for the accuracy of the information in this document. In particular, no guarantee can be given as to the suitability of the products described here for specific purposes. bemoko retains the right to alter the products and product information specified here. bemoko accepts no liability from events arising from the usage of the products described here. Issue of this document is not accompanied by licenses entitling you to use bemokoLive.

3

Dynamic multi-channel websites with bemokoLive

TABLE OF CONTENTS Purpose of this document .............................................................................. 4 Conventions used in the document ................................................................ 4 Overview ....................................................................................................... 5 Intents ........................................................................................................... 5 What are intents? ........................................................................................... 5 Intent Parameters ........................................................................................... 6 Theming Using Templates .............................................................................. 7 Device properties........................................................................................... 8 The Device API ................................................................................................ 9 Create YOUR tutorial project ......................................................................... 9 Plugins ........................................................................................................... 9 What is groovy? .............................................................................................. 9 How to author groovy ................................................................................... 10 Your first plugin ............................................................................................ 10 Plugin lifecycle .............................................................................................. 11 The dynamic multi-channel website example .............................................. 12 Create the plugins ......................................................................................... 13 Create the index intent ................................................................................. 14 Create the common template.html .............................................................. 15 Create the template site.css ......................................................................... 16 Create the common logo.html and logo.css .................................................. 16 First-pass at listing the movies ...................................................................... 17 Add dynamically scaled images ..................................................................... 19 Add transcoded thumbnail to our list page ................................................... 20 Create an intent to display the film details ................................................... 21 Create the film profile page .......................................................................... 21 Displaying the movie title ............................................................................. 22 Displaying the movie details ......................................................................... 23 Final results................................................................................................... 25

Purpose of this document

4

What next? .................................................................................................. 26

PURPOSE OF THIS DOCUMENT This document is the second document in the bemokoLive tutorial series and follows on from the previous tutorial document “Beginning multi-channel websites using bemokoLive”. The tutorial steps covered within this document will take the static site created previously and extend it to include additional pages and dynamic content pulled from an external data source. Further tutorials will follow on from where this document finishes. For further reference material and other tutorials, please see the bemoko developer’s wiki at http://www.bemoko.com/wiki This tutorial is design to take 1 hour to complete. CONVENTIONS USED IN THE DOCUMENT The following conventions are used throughout this document.
filename

Sections of code that you are asked to type, or representations of file system structure are presented like this. Bold text and non-bold text will be used when drawing attention to particular lines of code. Where you are creating a new file, the filename and path will be shown as a top in the top-right hand corner.

Tip boxes are used to draw your attention to particular tips or best practices that you may find useful in understanding particular concepts or providing assistance during the tutorials.

5

Dynamic multi-channel websites with bemokoLive

Note boxes are used as a warning to that you may need to pay attention to a point being made in order to avoid any pitfalls you may encounter later.

OVERVIEW In this tutorial we will start exploring some of the features that bemokoLive provides to allow you to develop dynamic, intelligent and reusable multichannel websites. We will start with a run through of intents – that is, mapping what a user wants to do – through to extending your website using the plugin architecture to integrate dynamic content into your pages. Along the way we will again look at some best-practices that can be applied to speed up your own development work and some of the features the bemokoLive provides to add intelligence to your pages. INTENTS WHAT ARE INTENTS? Throughout this tutorial we will be using the term "intent", but what exactly is an intent in the context of a bemokoLive site? Put simply it is capturing how the user wants to interact with our site and implementing what's necessary to achieve that. We configure intents as URI patterns within a file called site-config.xml, located in the root directory of our site. An example is shown below:
<?xml version="1.0" encoding="UTF-8"?> <site> <intents> <intent name="i" view="index.html" /> </intents> </site>

Intents

6

This creates an intent, named “i” which is mapped to the template file “index.html”. A user would request this intent using a URL similar to: http://localhost/live/i INTENT PARAMETERS Parameters can be applied to intents in one of two ways; either by adding them as request parameters or explicitly in the site-config.xml configurations file.
REQUEST INTENT PARAMETERS

Supposing we created an intent to display the value of something associated with a particular id, we would specify that on our page requests with URLs similar to this and reasonably expect our multi-channel website to display content relating to that item: http://localhost/live/show/id/123 or http://localhost/live/show?id=123
SITE-CONFIG PARAMETERS

We can also define parameters that will always be available to our intent explicitly in site-config.xml as follows:
<?xml version="1.0" encoding="UTF-8"?> <site> <intents> <intent name="i" view="index.html"> <param name="message">Hello World</param> </intent> </intents> </site>

We’ll see later when we look at page template theming how useful this method of specifying parameters is.
RETRIEVING INTENT PARAMETERS IN PAGES

The evaluation of intent parameters, regardless of which method is used to supply them, is done using FreeMarker interpolation functions which use a ${…} notation.

7

Dynamic multi-channel websites with bemokoLive

In order to retrieve the intent parameter value set in the site-config.xml example above we could create markup in the corresponding index.html as follows:
<div>${intent.message}</div>

This, as expected, will output the message “HelloWorld” in our page.
DEALING WITH MISSING INTENT PARAMETERS

What would happen in your pages if you try and retrieve the value for an intent parameter that doesn’t exist, a situation that could quite easily happen if you are relying on HTTP request parameters having being set? FreeMarker will replace the interpolated expression with an error message. To avoid errors occurring when intent parameters might not have been provided we should check the parameter has been set before we try and access it using the missing value test operator as follows:
[#if intent.message??]<div>${intent.message}</div>[/#if]

We can also specify default values to use in the case that an intent parameter is missing as follows:
<div>${intent.message!”no message”}</div>

Refer to http://www.freemarker.com for further uses of missing value tests THEMING USING TEMPLATES Looking back at the way we defined our intents, we will notice the fixed relationship between intent and the page that will be rendered in response. What that doesn’t give us is much flexibility in terms of sharing common page themes between intents. Using fixed intent parameters configured in site-config.xml allows us to take a different look at the way we structure our pages from the method we used in the earlier tutorial. Using intent parameters allows us to create common

Device properties

8

template theme pages we can reuse as the number of intents our site has increases. Let’s take a look now:
<site> <intents> <intent name="a" view="common.html?page=pageA.html"/> <intent name="b" view="common.html?page=pageB.html"/> </intents> </site>

Note that in this configuration example we’ve used a short hand to set the intent parameters in the style of URL query string parameters. This is equivalent to:
<site> <intents> <intent name="a" view="common.html"> <param name="page">pageA.html</param> </intent> <intent name="b" view="common.html"> <param name="page">pageB.html</param> </intent> </intents> </site>

This allows us to define a common look and feel in common.html, perhaps defining a page header and footer for example, and include a different page body for intents “a” and “b” as follows:
... header part of page ... <div>[#include intent.page]</div> ... footer part of page ...

DEVICE PROPERTIES We have already seen in the earlier tutorials how we use the attributes of devices to define our UIs, but let’s have a look now at accessing these

9

Dynamic multi-channel websites with bemokoLive

properties at runtime from within your web pages, and why you might want to. THE DEVICE API The object device is made available to the template which provides access to device capabilities, e.g :
<div>Device = ${device.name}</div> <div>Model = ${device.vendorName}</div> <div>Width = ${device.displayWidth}</div> <div>Height = ${device.displayHeight}</div>

See http://bemoko.com/wiki/Device_Capabilities for more details. CREATE YOUR TUTORIAL PROJECT We’re going to do some coding in the next section so get things started create the site called mytutorial2 by creating a folder called mytutorial2 under the bemoko/sites directory in your user’s home directory. On a unix system this is at ~/bemoko/sites. PLUGINS Plugins allow you to extend the functionality of the platform, such as pull in content from, for example, external feeds or a database. Of particular importance is that plugins can be changed on a running system making it quick to add the functionality you need. Plugins can be written in Java* or Groovy and can access any Java libraries (i.e. jars) that you already have available.
* Java syntax support is limited to that supported by Groovy, but since Groovy supports the majority of Java syntax, in most cases Java source can be used as is.

WHAT IS GROOVY? Groovy is a dynamic and agile scripting language, with a syntax that draws inspiration from a number of languages including Java, Ruby and Python. For

Plugins

10

full information, including developer guides, visit Groovy’s official home at http://groovy.codehaus.org/ HOW TO AUTHOR GROOVY There are plugins to add Groovy support available for most IDEs, but for the exercises we’re doing throughout this tutorial a text editor will be sufficient. YOUR FIRST PLUGIN Create a folder called plugins in your mytutorial2 site folder and in this folder create a plugin file called DateHelper.groovy as follows:
DISPLAY THE CURRENT TIME

plugins/DateHelper.groovy

class DateHelper { def getDate() { return new Date() } }
ACCESSING PLUGIN CONTENT

Then, create a file called site-config.xml in your mytutorial2 site folder which registers an intent called date, with the DateHelper plugin defined as a nested source element, as follows:
site-config.xml

<?xml version="1.0" encoding="UTF-8" ?> <site> <intents> <intent name="date" view="date.html"> <source name="DateHelper”/> </intent> </intents> </site>

11

Dynamic multi-channel websites with bemokoLive

Create a template ui/root/date.html to render this plugin
ui/root/date.html

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Date</title> </head> <body> <div>${content.DateHelper.date?time}</div> </body> </html>

... and access the page http://localhost:8080/live/mytutorial2/date

PLUGIN LIFECYCLE Several methods are executed on a plugin object during a plugin lifecycle. A plugin can optionally implement these methods, since they are only executed on a given plugin if that plugin provides the method.

Method

When?

Initialise(Map map)

When the plugin is loaded by the platform. The map object is a map of name value pairs defined in the site configuration for the plugin.

execute(Map map)

Once for every request made by a user, before the pages are rendered. The map object is a map of name

The dynamic multi-channel website example

12

value pairs provided by the intent parameters, e.g. query string parameters or REST parameters in the request URL

destroy()

Called by the platform before it stops using the plugin.

Each plugin can also have a scope defined to one of request (default), session or site. The scope controls when the plugin is loaded (and subsequently released) by the platform.

Scope

Effect

request

Plugin is initialised before each request and release after the request

session

The plugin is created for each new session and reused in that session throughout the lifecycle of that session.

site

The plugin is loaded once for a given site and the single instance of the plugin is reused for all requests. Note that by default the platform will reload the site plugin if you change the plugin, e.g. edit and save the code.

THE DYNAMIC MULTI-CHANNEL WEBSITE EXAMPLE

13

Dynamic multi-channel websites with bemokoLive

We will now take the concepts we’ve learnt about above to create a dynamic website extending the static site we created in the earlier tutorial. The site will have two pages; one to list the current latest cinema releases, and a second giving information on each one. To achieve this we will connect to and process an XML feed provided by www.services.filmtrailer.com

CREATE THE PLUGINS Let’s start by creating our plugin that will be used for accessing and processing the XML cinema feed. We’ll be creating two Groovy scripts for this – one is the plugin itself, and another to object to hold our movie feed data. Create the movie bean with the code below:
plugins/Film.groovy

class def def def def def def }

Film{ id title actors=[] directors=[] description image

And the plugin to create instances of this Film bean from the XML feed:
plugins/FeedReader.groovy

class FeedReader extends AbstractPlugin { private def url private def films void initialise(Map map) { url=map.url }

The dynamic multi-channel website example

14

List getFeed() { def feedResponse = new XmlSlurper(false,false).parse(url) def filmList=[]; feedResponse.movies.movie.each { def product = it.regions.region.find { it.@name=='UK' } .products.product.find { it.@name=='cinema' } def film=new Film( id : it.@movie_id, title : product.product_title, actors : it.actors.actor.list(), directors : it.directors.director.list(), description : product.description, image : it.regions.region.find { it.@name=='UK' } .pictures.picture.find { it.@type_name=='Video Still 1' } .url.text() ) filmList+=film } films=filmList return films } Film getFilm(def item) { if(!films) getFeed() return films.find{it.id==item} } }

Refer to Groovy documentation at http://groovy.codehaus.org/Documentation to understand how groovy XML processing works in the code above.

You can grab source code from the tutorial2 site in the bemokoLive war if you wish.

CREATE THE INDEX INTENT The index intent (or “i” for short) will be the page that lists the latest films retrieved using the plugin above.

15

Dynamic multi-channel websites with bemokoLive

Create the “i” intent by creating a site-config.xml in the root of our project folder using the content below:
site-config.xml

<site> <content-sources> <source name="feed" plugin="FeedReader" scope="site"> <param name="url">http://uk.feed.previewnetworks.com/cinema/now-5</param> </source> </content-sources> <intents> <intent name="i" view="template.html?page=list.html"/> </intents> </site>

This will (1) hook in the FeedReader plugin as plugin called feed and (2) register the URI /i to our intent.

CREATE THE COMMON TEMPLATE.HTML Both our pages will several common attributes: The same <head/> html content, the same logo at the top of the page and the same page body styling for example. We will now create the template page that will implement these common parts for all our pages. Create ui/root/template.html with the content below.
ui/root/template.html

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>At the movies</title> <link rel="stylesheet" type="text/css" href="site.css" /> </head> <body> [#include "logo.html"] [#if intent.page??]

The dynamic multi-channel website example

16

[#include intent.page] [/#if] </body> </html>

Notice particularly the line [#include intent.page] – This is where our intentspecific pages will be included. From the site-config.xml intent we configured in the earlier step, we can see that any requests for the URI /i will map to the “i” intents which will set the intent parameter page with the value “list.html”.

CREATE THE TEMPLATE SITE.CSS As we did in the earlier tutorials, let’s now create the site.css global stylesheet with the content below.
ui/root/site.css

[#-- common styling for all pages --] * { margin: 0px; padding: 0px; font-family: Sans-Serif; color: #fff; } body { background-color: #000; }

CREATE THE COMMON LOGO.HTML AND LOGO.CSS Again as with the first tutorial, we will now create logo.html and logo.css. Let’s start with the root UI:
ui/root/logo.html

<div id="logo">AT THE MOVIES</div>

17

Dynamic multi-channel websites with bemokoLive

ui/root/logo.css

div#logo { border-bottom: 1px solid #fff; }

Then, for the 240 UI versions of these files with the content below. Refer to the earlier tutorial if you need reminding why we create a new version for the 240 UI.
ui/240/logo.html

<div id="logo"><img src="images/logo.png" /></div>

ui/240/logo.css

div#logo img { display: block; } div#logo { background:url('images/logo_bg.png') repeat-x top right; }

Finally we need to add a reference to our site.css to include the new logo.css. Add the following line to ui/root/site.css we created earlier:
ui/root/site.css

… [#include "logo.css"]

FIRST-PASS AT LISTING THE MOVIES We have our intent configured and our plugin created, so let’s now put everything together and create our list.html page to, as you might have expected, display a list of the latest movies processed by our feed plugin.

The dynamic multi-channel website example

18

Create list.html in the root UI from the content below:
ui/root/list.html

<div id="title">Latest movie releases</div> [#list content.feed.getFeed() as film] <div class="listitem"><a href="/view/id/${film.id}">${film.title}</a></div> [/#list]

And the associated list.css, also in the root UI:
ui/root/list.css

div.listitem { padding:3px; }

One final step to carry out is to reference list.css from our global site.css. Add the line below to ui/root/site.css:
ui/root/site.css

… [#include "list.css"]

Open http://localhost:8080/live/mytutorial2/i in your mobile browser to see the list of movies displayed:

19

Dynamic multi-channel websites with bemokoLive

ADD DYNAMICALLY SCALED IMAGES Well, so far so good: We’ve created our first dynamic page, but we can do a lot more with this. Notice when we created our movie plugins we captured an image URL for each film. We can’t do much with this at the moment as the images the feed provides are too large to display on a mobile screen. Luckily bemoko provides an image transcoding plugin on their community site. Download the imagetranscoder plugin from http://github.com/bemoko/imagetranscoder and install according to the README file. This should leave you with the following files in your site folder:
plugins/FeedReader.groovy plugins/Film.groovy plugins/imagetranscoder/ImageTranscoder.groovy plugins/imagetranscoder/ImageTranscodeRenderer.groovy

And the following in your site-config.xml
site-config.xml

<site> <content-sources> <source name="feed" plugin="FeedReader" scope="site"> <param name="url">http://uk.feed.previewnetworks.com/cinema/now-5</param> </source> <source name="transcoder" plugin="imagetranscoder.ImageTranscoder" scope="site"/> </content-sources> <intents> <intent name="i" view="template.html?page=list.html"/> <intent name="t" type="renderer"> <renderer name="imagetranscoder.ImageTranscodeRenderer"/> </intent> </intents> </site>

The dynamic multi-channel website example

20

Only use image transcoders on photograph-style images. Using them on logos or icons may result in unacceptable loss of detail. For these types and other images where fine detail is important, make sure to create the images in the sizes you require. ADD TRANSCODED THUMBNAIL TO OUR LIST PAGE Let’s now make use of the image URLs to feed provides and the functionality of our new image transcoder. We’ll do this only for the large screen devices, so create list.html in the 320 UI:
ui/320/list.html

<div id="title">Latest movie releases</div> [#list content.feed.getFeed() as film] <div class="listitem"> <img src="${content.transcoder.uri('64.jpeg',film.image)}" alt="${film.title}"/> <a href="/view/id/${film.id}">${film.title}</a> </div> [/#list]

Notice the transcode rule we specified: ’64.jpeg’. This instructs the transcoder plugin to resize the image at the URL ${film.image} to 64 pixels wide, and set the format to jpeg. Now create list.css in the 320 UI to accompany the html above:
ui/320/list.css

div.listitem { padding:3px; } div.listitem img{ padding-right:3px; }

21

Dynamic multi-channel websites with bemokoLive

CREATE AN INTENT TO DISPLAY THE FILM DETAILS The links we added to the earlier list.html should have given you a clue as to what we will name our next intent, which will be used to display each film profile. Add the intent named “view” to your site-config.xml by adding the following lines to the “intents” section:
site-config.xml

<intent name="view" view="template.html?page=view.html"/>

Notice how we are reusing our earlier common template.html, but this time setting the “page” parameter to view.html. CREATE THE FILM PROFILE PAGE We will be replicating the way we designed the title, image and movie details from the previous tutorial for this step, so let’s create view.html which we will

The dynamic multi-channel website example

22

further split into title and movies content sections. Create view.html in the root UI form the content below:
ui/root/view.html

[#assign film=content.feed.getFilm(intent.id)] [#include "title.html"] [#include "content.html"]

The first thing we do is call the getFilm method on our film feed plugin with the value of the intent parameter “id” passed as a variable. We assign the result of this call to a FreeMarker variable called film, which due to the way variable scoping works in FreeMarker, will be available to the two page fragments we subsequently include. DISPLAYING THE MOVIE TITLE Create title.html and title.css in the root UI from the content below:
ui/root/title.html

<div id="title">${film.title}</div>

ui/root/title.css

div#title { padding: 3px; font-weight: bold; text-align: center; }

As before when we introduced a new css fragment, add a reference to title.css in site.css by adding the following line:
ui/root/site.css

… [#include "title.css"]

23

Dynamic multi-channel websites with bemokoLive

Notice how we were able access the film title using using ${film.title}. The first part of this expression, “film” refers to the variable we set in view.html earlier, which is an instance of the Film Groovy class we created at the beginning of these exercises. Complete this step by showing a film image for 240 UIs and above by creating the following version of title.html in the 240 UI:
ui/240/title.html

<div id="title"> <div>${film.title}</div> <div><img src="${content.transcoder.uri('230.jpeg',film.image)}" alt="${film.title}"/></div> </div>

With the image transcoder plugin we used earlier, we can again scale the image provided by the feed to fit the screen for our UI – in this case we scale to 230 pixels wide to fit comfortably on the 240 pixel wide UI devices.

DISPLAYING THE MOVIE DETAILS Let’s finish things off now by creating the final content.html page fragment to display the movie details.

The dynamic multi-channel website example

24

Create content.html and content.css in the root UI from the content below.
ui/root/content.html

<div id="content"> <div>${film.description}</div> </div>

Ui/root/content.css

div#content { padding: 3px; } div#content div { padding: 3px 0px; }

And as before, add content.css to our global site.css in the root UI:
ui/root/site.css

… [#include "content.css"]

As with the first tutorial, we will take advantage of the larger screen size provided by the 320 UI devices and create a version of the content page fragments to include further film information. Create content.html and content.css from the content below:
ui/320/content.html

<div class="note"> <div> <span class="highlight">Directed by:</span> [#list film.directors as director] ${director}[#if director_has_next], [/#if] [/#list] </div> <div> <span class="highlight">Starring:</span> [#list film.actors as actor] ${actor}[#if actor_has_next], [/#if] [/#list]

25

Dynamic multi-channel websites with bemokoLive

</div> </div> <div id="content"> ${film.description} </div>

ui/320/content.css

div#content { padding: 3px; } div.note { padding:3px; font-style: italic; border-top:1px solid #fff; border-bottom:1px solid #fff; } span.highlight { font-weight: bold; }

FINAL RESULTS Let’s now take a look at the finished site by again loading http://localhost:8080/live/mytutorial2/i in your browser. We can see what this should look like from the diagram below.

What’s next?

26

WHAT’S NEXT? With tutorial one and two under your belt you now have seen how to create mobile optimised UIs and how to pull in dynamic content with bemokoLive. You may be interested to take this tutorial a little further. Perhaps you’d want to:  Add caching to the feed so that the feed is not retrieved from the remote server on each request.  Make the site more resilient to an un-reliable feed. For example if the remote feed is not available, display the last known good feed. There is a lot more information on the bemoko developer wiki @ http://bemoko.com/wiki which will help you through this. Take a look at some of our plugins which we have open-sourced and made available to you to

27

Dynamic multi-channel websites with bemokoLive

both use directly in your site and also to give you more ideas on how create mobile friendly web sites.

Sponsor Documents

Or use your account on DocShare.tips

Hide

Forgot your password?

Or register your new account on DocShare.tips

Hide

Lost your password? Please enter your email address. You will receive a link to create a new password.

Back to log-in

Close