MotherApp Engine

Tutorial

MotherApp Tutorial

Part 4: Offline Application

You can use MotherApp Engine to create content that can be navigated in offline (no network). This tutorial will guide you to understand:

  1. Storing pages into local storage
  2. Local database
    1. Add/Delete/Query database
    2. MotherApp Engine Template using database
  3. Trigger actions after the page is loaded
  4. Examples:
    1. Sync content for offline access
    2. Bookmark article
    3. Offline search

1. Storing pages into local storage

In MotherApp Engine, there are two "wf_style", "fetch" and "force_fetch", specifying to store pages into the local storage. So, the stored pages can be retrieved in the future without access the network.

Examples:

<a href="article_1.html" wf_style="fetch button">Article 1</a>
<a href="article_1.html" wf_style="force_fetch button">Article 1</a>

When the user click the first button, the "article_1.html" (specified with "fetch") will be retrieved from the network at the first time. Then "article_1.html" will be stored in the local storage. So, the same link ("article_1.html") will be retrieved from the local storage immediately next time. So the user can view the content of "article_1.html" no matter the device connects to the internet.

Sometimes, you may want to skip the cache and load the page directly from the network. Then, you can use "force_fetch" to do it. The link specified with "force_fetch" will be retrieved from the network and store it in the local storage.

2. Local database

MotherApp Engine provides developers some methods to add, delete and query records to/from the local database.

2.1. Add/Delete/Query database

2.1.1. Add

MotherApp Engine defines a special url scheme to add (key, value) pair to the local database. The syntax is wf://device/db/add?key=xxx&value=yyy

        Add Shop
    

For better illustration, the query string part of url is urldecoded as following:

parametervalueexplain
key shop001 key of the record
value {name%20}{address%20} value of the record. With "{" "}", MotherApp Engine would try to find the parameters in the query string to substitute the string into the "value". "%" is used to left-space-padded the variable. So the result is "             ABCShop             SanJose".
name ABCShop used for substitution
address SanJose used for substitution
redirect shop_added.html After adding the record, "shop_added.html" will be retrieved.


2.1.2. Delete

Deleting a record is similar to add a new record. The syntax is wf://device/db/delete?key=xxx


2.1.3. Query

There are two ways you can get the record(s) from the local database.

  • MotherApp Variable: [wf:db:(key)]
    Search
    "[wf:db:searchkey]" (decoded value of "%5Bwf%3Adb%3Asearchkey%5D") will be replaced by querying the value of the record with the key equal to "searchkey".
  • wf://device/db/query?...
    Query the local database and return the records. Normally, it is used with the MotherApp Template to render the user interface with queried records.
    Examples:
    • Return records with the key started with "15":
      wf://device/db/query?subkey0:2=eq15
    • Return records with the key started with "15":
      wf://device/db/query?subkey0:2=eq15
    • Return records with the key started with "15" or "19" or "20":
      wf://device/db/query?subkey0:2=eq15,eq19,eq20
    • Return records for substring(key, 0, 2) >= '15' and substring(key, 2, 4) = 'sun':
      wf://device/db/query?subkey0:2=ge15&subkey2:5=eqsun
    • Return records with the first two characters between "15" and "20":
      wf://device/db/query?subkey0:2=ge15-le20
    • Return 1 record if no result found for wf://device/db/query?subkey0:2=ge15-le20. Otherwise, return 0 record.
      wf://device/db/query?subkey0:2=ge15-le20&result_filter=is_empty

For more details, please read our reference.


2.2. MotherApp Engine Template using database

MotherApp Engine defines a way to render the user interface based on query result from the local database. "wf_source" attribute is used for this purpose. The value of the "wf_source" attribute is the database query url introduced in previous section. The returned records are used to render the user interface. It's better using examples to illustrate the power of MotherApp Engine Template.

Assume there are several records in the local database:

keyvalue
Shop001 ABCShopHK
Shop002 AppShopUS
Shop003 WebShopJP
Shop004HTMLShopUK
Shop005  MAShopHK
Link001http://www.google.com/
Link002http://www.apple.com/

Following is the html source:

<html>
  <body>
    <title align="center">Shops</title>
    <table>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">{{counter}}</td>
        <td width="35%">{{value0:8}}</td>
        <td width="60%">{{value8:10}}</td>
      </tr>
    </table>
  </body>
</html>

The "wf_source" attribute is defined in "tr" tag. MotherApp Engine would query the database according to the query defined in the attribute. ("wf://device/db/query?subkey0:4=eqShop" searchs for records which key is started with "Shop"). In this examples, there are 5 records returned (i.e. Shop001, Shop002, ..., Shop005).

Then MotherApp Engine would replicate the "tr" tag according to the searched results. In the example, 5 "tr"s are replicated. There are some special variables can be used such as {{counter}}, {{value}} (no space) and {{key}} to fill the content. For {{value}}, indexes can be used to retrieve a portion of the string.

So the result is:

<html>
  <body>
    <title align="center">Shops</title>
    <table>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">1</td>
        <td width="35%">ABCShop</td>
        <td width="60%">HK</td>
      </tr>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">2</td>
        <td width="35%">AppShop</td>
        <td width="60%">US</td>
      </tr>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">3</td>
        <td width="35%">WebShop</td>
        <td width="60%">JP</td>
      </tr>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">1</td>
        <td width="35%">HTMLShop</td>
        <td width="60%">UK</td>
      </tr>
      <tr wf_source="wf://device/db/query?subkey0:4=eqShop">
        <td width="5%">1</td>
        <td width="35%">MAShop</td>
        <td width="60%">HK</td>
      </tr>
    </table>
  </body>
</html>

3. Trigger actions after the page is loaded

3.1. navigation_background

Let's introduce a new concept called "navigation_background". The "wf_style" attribute of a link contains "navigation_background". The page will be loaded in the background (i.e. no user interface rendering). All the images will be loaded in the page will be loaded too.

<a href ="article_1.html" wf_style="button navigation_background">load in background</a>

3.2. onload, onload_foreground, onload_background

When a link is defined with "onload" in the "wf_style" attribute, the link will be triggered automatically after the page is loaded. For examples,

<a href ="article_1.html" wf_style="navigation_background onload"></a>
The page "article_1.html" will be loaded automatically after the current page (the page contains this link) is loaded. And the page is loaded in background in this example.
<a href ="wf://device/db/add?key=load_time&value=20100629170800" wf_style="onload"></a>
The database action (insert (load_time, 20100629170800)) will be triggered automatically after the page is loaded.

Sometimes, you may want to triggered the link only when the page is in the foreground (see 4.1.). You can use "onload_foreground" to trigger the link. Vice versa, "onload_background" is used to trigger the link when the page is loaded in background.

Caution: be careful that the page is looped back and created a infinite cycle of loading

4. Examples

In this section, three examples will be given to illustrate the combination usage of above features to make offline application

4.1. Sync content for offline access (Download)

Problem: There is a list of articles. We want to cache all the articles automatically in background when users first launch the application

Solution: We can make use of onload, fetch and navigation_background to complete the task

First, in the article list page, we can add an "onload" link (line 4) to trigger a sync (sync.html) action automatically in background. Following is the article list page:

<html>
<body>
  <wf_titlebar><title align="center">Articles</title></wf_titlebar>
  <a href="sync.html" wf_style="navigation_background onload"></a>
  <table wf_style="fullscreen">
    <tr wf_href="article_1.html"><td wf_style="padding">Getting Started</td></tr>
    <tr wf_href="article_2.html"><td wf_style="padding">MA Debugger</td></tr>
    <tr wf_href="article_3.html"><td wf_style="padding">GeoCamera</td></tr>
    <tr wf_href="article_4.html"><td wf_style="padding">Offline application</td></tr>
  </table>
</body>
</html>

Then, in the sync page (sync.html), fetch and onload can be used to load the articles and save them into local storage in the background after the sync page is loaded. Following is the sync page:

<html>
<body>
  <a href="article_1.html" wf_style="onload fetch"></a>
  <a href="article_2.html" wf_style="onload fetch"></a>
  <a href="article_3.html" wf_style="onload fetch"></a>
  <a href="article_4.html" wf_style="onload fetch"></a>
</body>
</html>

So, all the articles (article_1.html, article_2.html, ...) can be automatically loaded into the local storage. If the user click the article "MA Debugger", it is loaded from the local storage directly rather than from the internet. Thus, the articles can be read in offline mode.

You can download the examples code here: Download


4.2. Bookmark article (Download)

Problem: How to bookmark article locally

Solutions: Make use of local database and MotherApp template to implement a bookmark functionality

In the article, a database inserting link (line 5) can be used to add the bookmark to the database as shown:

<html>
<body>
<wf_titlebar>
    <title align="center">Getting Started</title>
    <a href="wf://device/db/add?key=fav001&value=++++Getting Started++++++article_1.html" align="right">+</a>
</wf_titlebar>
<div>
Consectetuer adipiscing elit. Nam pede erat, porta eu, lobortis eget, tempus et, tellus. Etiam neque. Vivamus consequat lorem at nisl. Nullam non wisi a sem semper eleifend. Donec mattis libero eget urna. Duis pretium velit ac mauris. Proin eu wisi suscipit nulla suscipit interdum. Aenean lectus lorem, imperdiet at, ultrices eget, ornare et, wisi.
</div>
...
</body>
</html>

When user click the bookmark link, ("fav001", "    Getting Started      article_1.html") is added to the local database.

Then, we can make use of MotherApp template to inflate the bookmarks into the table:

<html>
<body>
  <wf_titlebar>
    <title align="center">Bookmarks</title>
  </wf_titlebar>
  <table wf_style="fullscreen">
    <tr wf_source="wf://device/db/query?subkey0:3=eqfav" wf_href="{{value20:40}}">
      <td wf_style="padding">{{value0:20}}</td>
    </tr>
  </table>
</body>
</html>

line no.codedescription
7wf://device/db/query?subkey0:3=eqfavquery the database with key which started with "fav"
7{{value20:40}}The substring [20,40) of value of the record is filled in the "wf_href" attribute (note that the output will be space-trimmed)
8{{value0:20}}The substring [0,20) of value of the record is filled in the content

So, the result will be (if only first article is bookmarked):

<html>
<body>
  <wf_titlebar>
    <title align="center">Bookmarks</title>
  </wf_titlebar>
  <table wf_style="fullscreen">
    <tr wf_href="article_1.html">
      <td wf_style="padding">Getting Started</td>
    </tr>
  </table>
</body>
</html>

You can download the examples code here: Download


4.3. Offline search (Download)

Problem: How to search a website in the database

Solutions: Make use of local database: add and query and MotherApp template to implement the offline search functionality

First, you can use following code to import the data:

...
<div wf_source="wf://device/db/query?subkey0:3=eqwww&result_filter=is_empty">
    <a href="db_data.html" wf_style="onload navigation_background"></a>
</div>
...

wf_source="wf://device/db/query?subkey0:3=eqwww&result_filter=is_empty" is used for checking the data is already in the database, if not, it would load "db_data.html" in background.

Second, create a <form> to let user input the search key. However, offline search should not use the server script to construct a proper wf://device/db/query. So, [wf:db:key] is introduced to help for constructing the query.

...
<form action="wf://device/db/add">
  <table wf_style="fullscreen">
    <tr><td>
      <input type="text" wf_style="search" name="value"/>
      <input type="hidden" name="key" value="searchkey"/>
      <input type="hidden" name="redirect" value=""/>
    </td></tr>
  </table>
</form>
...
line no.codedescription
2<form action="wf://device/db/add">Tricks for using the form get to help to build the db add query
5The search query input by the user
6searchkeyThe key for search
7redirectredirect parameter
When the user input a keyword and click search, MotherApp will construct a proper db add action (e.g. wf://device/db/add?key=searchkey&value=Mother&redirect=). So, (searchkey, MotherApp) will be added to the database and the page is redirect to the current page again ("") in this example. After that, [wf:db:searchkey] can be used to construct a proper query in the "wf_source" attribute:
...
<table wf_style="fullscreen">
  <tr wf_source="wf://device/db/query?subkey0:3=eqwww&value=li%5Bwf%3Adb%3Asearchkey%5D" wf_href="{{value30:80}}" wf_style="browser_launched">
      <td wf_style="padding">{{value0:30}}</td>
  </tr>
</table>
...
Line 3 shows the merit of using "[wf:db:searchkey]" (decoded value of "%5Bwf%3Adb%3Asearchkey%5D"). So the query becomes "wf://device/db/query?subkey0:3=eqwww&value=liMother". It searchs for records with the key started with "www" and the value contains "MotherApp".

You can download the examples code here: Download

What Resources Are Available to Me as a Developer?

  • MotherApp HTML Reference
    Click here to see the complete reference for MotherApp HTML. You can select having the code elements displayed by category, alphabetically, or with associated screen shots.
  • Development Tools
    • Click here to use the MotherApp Debugger.
      Use the debugger test your application using a web browser (the Safari 4, Firefox 3.5 and Google Chrome browsers are recommended). The generated user interface may differ somewhat from the display on any particular device (since the app will display natively, and therefore differently, on each platform), but the debugger accepts the same MotherApp HTML as the devEngine. It will allow you to to check the syntax for your MotherApp HTML pages.
    • Click here to use the MotherApp Sandbox
      The MotherApp sandbox helps generates the testing version of app that could be actually deployed to the devices.
    • Click here to view our set of sample apps.
  • More Information
    • Click here to view our list of MotherApp "How to"s. For example, "how to deliver your completed app," or "how to launch the video player."
    • Click here to view the answers to our Frequently Asked Questions (FAQ)
    • Click here to go to our Support Forum.