Skip to content
Ruben Gamez edited this page Jun 3, 2016 · 22 revisions

Projects

A project is instance of fieldtrip open. It contains a theme and a list of plugins it wishes to enable.

Theme

A fieldtrip theme contains two stylesheets:

  • A jQuery Mobile theme, preferably create by ThemeRoller. The stylesheet will be found at: theme/css/jqm-style.css. It is important to use the correct version and copy the images in the download zip file to theme/css/images/.
  • A stylesheet for overriding the core stylesheet. It will be found at: theme/css/style.css

Plugins

The json file theme/project.json will define a list of plugins the project wishes to enable. The following is an example:

{
    ...
    "plugins": {
        "cordova": [
            "org.apache.cordova.camera@0.2.7",
            "org.apache.cordova.console@0.2.7",
            "org.apache.cordova.device@0.2.8",
            "org.apache.cordova.file@1.0.0",
            "org.apache.cordova.file-transfer@0.4.1",
            "org.apache.cordova.geolocation@0.3.6",
            "org.apache.cordova.inappbrowser@0.3.1",
            "org.apache.cordova.media@0.2.8",
            "org.apache.cordova.media-capture@0.2.7"
        ],
        "fieldtrip": {
            "offline-maps": "0.0.1",
            "sync", "git@github.com:edina/fieldtrip-sync.git",
            "gps-tracking": "git@github.com:edina/fieldtrip-gps-tracking.git -b mybranch"
        }
    }
}

Cordova

Cordova plugins documentation

Fieldtrip

  • offline-maps: will use the release tagged 0.0.1.
  • sync: will use the master branch of the plugin found at the defined git repository.
  • gps-tracking: will use the mybranch branch of the defined git repository.

For details on fieldtrip plugin development see plugin development documentation.

App icons, splash screens and code patches

Each platform has a specific directory structure, we mirror that structure into the project/platforms directory in order to customise some aspects of the app, primarily for adding custom icons and splash screens but also for patching or adding code. Every time the fab install_project:{platform} or the update_app:{platform} is executed, the content of project/platforms/{platform} is copied into the {runtime}/platforms/{platform} directory.

Icons and Splash Screens

The easiest way of doing this is checking the {runtime}/platforms and copy the files to override into the project/platforms always preserving the directory structure. Alternatively, you can check the each platform configuration files to find where the assets are expected.

  • Android {runtime}/platforms/android/AndroidManifest.xml
  • iOS {runtime}/platforms/ios/{project_name}/{project_name}-Info.plist

Code patches

  • iOS

    Patching the MainViewController in order to add padding into the webview is recommended.

Templates

All HTML in fieldtrip open is templated with the core providing bare bone templates and data json files as a starting point for a project. In addition, plugins can also provide templates and default data files for new pages that they wish to introduce to the app. It is the role of the project to provide the content of the main landing pages that diverge from the default layout.

Add New Button

A project can add a new button to the Home page by adding an index.json to src/templates. The following json object adds a Saved button that will open saved-maps.html when clicked:

{
    "body": {
        "section1": {
            "items": {
                "item2": {
                    "div": {"class": "ui-block-b"},
                    "a": {"href": "saved-maps.html"},
                    "img": {"src": "css/images/saved.png", "alt": "Save Map"},
                    "title": "Saved"
                }
            }
        }
    }
}
  • section1: refers to the Maps section of the Home page
  • item2: is the id of the button and should be unique if the button is new or the same if replacing an existing button
  • ui-block-b: places the button in the second column of the section, see JQM Grid Layout docs

A project can add a new button to the Capture page by adding an capture.json in src/templates.

Add Header Button

A project or plugin can add a new button to the main header of the app by adding the following to the page json file where it should appear:

{
    "header": {
        "buttons" : {
            "exit": {
                "id": "home-exit",
                "data-role": "button",
                "data-inline": "true",
                "data-transition": "none",
                "value": "Exit"
            }
        }
    }
    ...
}

Add New Footer Tab

A project can add a new footer new tab, and landing page for the tab, by providing a footer.json in src/templates. The following json object adds a Download tab that will open download.html when clicked:

{
    "download": {
        "name": "Download",
        "href": "download.html",
        "class": "download-button",
        "data-icon": "custom"
    }
}

Removing Elements

For overriding/getting rid of elements on the core system (e.g. the footer on index page or some of the buttons of the main body) you need to add empty objects on the index.json, for example:

"footer" : {},
"body": {
	"sections":
    	{"items" : {"item1" : ""}
     }
 }

For a fuller example see: https://github.com/edina/spatial-memories/blob/master/src/templates/index.json.

Internationalisation

Basics

The project uses the i18next jQuery plugin of the i18next library for handling the internationalisation of app.

For every component of the app (core, project and plugins) the locales are stored in the src/locales/ directory of each one and the translations are grouped by language and namespaces in a key/value json and stored using the {lang}/{namespace}.json convention.

fieldtrip-open
├── src
│   └── locales
│       ├── el
│       │   ├── common.json
│       │   └── index.json
│       ├── en
│       │   ├── common.json
│       │   └── index.json
│       └── es
│           ├── common.json
│           └── index.json
├── project
│   └── src
│       └── locales
│           ├── el
│           │   ├── common.json
│           │   └── index.json
│           ├── en
│           │   ├── common.json
│           │   └── index.json
│           └── es
│               ├── common.json
│               └── index.json
└── plugins
        └── project
            └── src
                 └── locales
                     ├── el
                     │   ├── common.json
                     │   └── index.json
                     ├── en
                     │   ├── common.json
                     │   └── index.json
                     └── es
                         ├── common.json
                         └── index.json

When the app is built the translations are merged under the www/locales/ directory using the following order from lesser to higher priority: core > plugins > project. Also, a catalog.json will be created listing the languages and namespaces available.

Creating a new language for the core

In order to create a new language and listing it correctly as a language use the following procedure:

  1. Create a directory for the language under src/locales using the ISO 639-1 language code.

  2. In that directory create a common.json file with a property language_name holding the name of the new language.

For example for starting the Welsh language translations create:

  • src/locales/cy/common.json
{
    "language_name": "Cymraeg"
}

Creating a new translation string

The most important fact to know when creating or updating templates for the app is that the resulting html after compiling the templates should contain the data-i18n property in each DOM element to be translated, the value should be namespace:translation_string_name, a simple example is the string Exit which is stored in the common namespace,

  1. Create or update the exit property for the English language (app's default language) in the common.json file (fieldtrip-open/src/locales/en/common.json).

    {
        "exit": "Exit"
    }
    
  2. Add other language translations, this can be done manually editing the appropriate file or using the Transifex service (fieldtrip-open/src/locales/es/common.json).

    {
        "exit": "Salir"
    }
    
  3. Use it in the templates, for example a button with the label Exit:

    <a data-i18n="common:exit" data-role="button"><a>
    

Merging the translations

There is a fabric task that can be executed to update the runtime locales manually:

$ fab merge_locales

Advanced examples

Combining templates and translations allows to use more complex patterns in the app.

Adding a default value to the DOM

With English as a default language it make sense to add a default string into the DOM elements.

  1. In the template (src/templates/map.html)

    <h2 data-i18n="{{sections.title.i18n}}">{{sections.title.en}}</h2>
    
  2. In the variables for the template (src/templates/map.json)

    "body": {
        "section1": {
            "title": {
                "i18n": "map:section_maps",
                "en": "Maps"
            }
        }
    }
    
  3. In the locales

  • src/locales/en/map.json
{
    "section_maps": "Maps"
}
  • src/locales/es/map.json
{
    "section_maps": "Mapas"
}

Generate HTML

The generate_html fabric task will need to be run after a change to templates or data files:

$ fab generate_html

Examples

Plugins

Fieldtrip open plugins allows projects to add functionality to the fieldtrip platform.

Core Plugins

Adding bespoke plugins

javascript

Plugins can add features or change default behaviour by creating a requirejs module in src/www/js/<plugin_name>.js. For example:

define(['map', './mymodule.js'], function(map, mymodule){
    $(document).on('pageshow', '#myplugin-page', function(){
        // do something
    });
});

The above snippet will load a core module map and a module named mymodule.js that will be provided by the plugin.

templates

All new pages added by a plugin should be created as templates in src/templates

settings

Settings widgets can be added by plugins by add creating a settings.html template in src/templates, e.g:

<div data-role="fieldcontain">
  <label for="settings-debug-gps">Debug GPS:</label>
    <select id="settings-debug-gps"
      data-role="slider"
      name="settings-entry">
      <option value="off">Off</option>
      <option value="on">On</option>
    </select>
</div>

The current value can be retrieved by calling the get method on the settings module, e.g:

define(['settings'], settings){
    if(settings.get('debug-gps')){
        // do something
    }
});

stylesheet

Plugins can add a stylesheet by via javascript, e.g:

$('head').prepend('<link rel="stylesheet" href="plugins/<myplugin>/css/style.css" type="text/css" />');

Release Instructions

Install Dependencies

For releasing the plugin you need to ensure the dependencies are first installed:

$ npm install

Patch, Minor or Major

The default is to release incrementing the patch number:

$ npm run release

For minor/major:

$ npm run release minor
$ npm run release major

Interactive Prompts

You will been asked a series of questions that you need to respond to. E.g:

Release source repo
[?] Show updated files? No
[?] Commit (Release 0.7.2)? Yes
[?] Tag (0.7.2)? Yes
[?] Push? Tes
[?] Publish "fieldtrip-sync" to npm? (y/N)

Commit, Tag and Push must be answered Yes. Publish should be answered Yes if the plugin has never before been registered with npm.

If you want to run the release non-interactively you can do:

$ npm run release -- -n

First Time Set-up

If you need to create a new fieldtrip plugin you need to add 2 packages in your devDependencies section of package.json:

$ npm install --save-dev jshint
$ npm install --save-dev release-it

Then add this part of code in your scripts object:

"lint": "node_modules/jshint/bin/jshint src/www/js/**.js",
"release": "npm run lint && node_modules/release-it/bin/release.js"

Add a .jshintrc and .release.json to root of repository:

  • .jshintrc
{
    "camelcase": true,
    "browser": true,
    "globalstrict": true,
    "globals": {
        "console": false,
        "define": false,
        "device": false,
        "FileTransfer": false,
        "LocalFileSystem": false,
        "localStorage": false,
        "location": false,
        "module": false,
        "navigator": false,
        "notification": false,
        "OpenLayers": false,
        "plugins": false,
        "require": false,
        "webdb": false,
        "FileTransferError": false
    },
    "multistr": true,
    "indent": "4",
    "jquery": true,
    "maxparams": "4"
}
  • .release.json
{
    "non-interactive": false,
    "dry-run": false,
    "verbose": false,
    "force": false,
    "pkgFiles": ["package.json","bower.json"],
    "increment": "patch",
    "commitMessage": "Release %s",
    "tagName": "%s",
    "tagAnnotation": "Release %s",
    "buildCommand": false,
    "distRepo": false,
    "distStageDir": ".stage",
    "distBase": "dist",
    "distFiles": ["**/*"],
    "private": false,
    "publish": false,
    "publishPath": "."
}

Clone this wiki locally