-
Notifications
You must be signed in to change notification settings - Fork 8
Develop
A project is instance of fieldtrip open. It contains a theme and a list of plugins it wishes to enable.
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
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"
}
}
}
- 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.
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.
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
-
iOS
Patching the MainViewController in order to add padding into the webview is recommended.
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.
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.
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"
}
}
}
...
}
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"
}
}
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.
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.
In order to create a new language and listing it correctly as a language use the following procedure:
-
Create a directory for the language under
src/localesusing the ISO 639-1 language code. -
In that directory create a
common.jsonfile with a propertylanguage_nameholding the name of the new language.
For example for starting the Welsh language translations create:
- src/locales/cy/common.json
{
"language_name": "Cymraeg"
}
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,
-
Create or update the
exitproperty for the English language (app's default language) in thecommon.jsonfile (fieldtrip-open/src/locales/en/common.json).{ "exit": "Exit" } -
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" } -
Use it in the templates, for example a button with the label
Exit:<a data-i18n="common:exit" data-role="button"><a>
There is a fabric task that can be executed to update the runtime locales manually:
$ fab merge_locales
Combining templates and translations allows to use more complex patterns in the app.
With English as a default language it make sense to add a default string into the DOM elements.
-
In the template (src/templates/map.html)
<h2 data-i18n="{{sections.title.i18n}}">{{sections.title.en}}</h2> -
In the variables for the template (src/templates/map.json)
"body": { "section1": { "title": { "i18n": "map:section_maps", "en": "Maps" } } } -
In the locales
- src/locales/en/map.json
{
"section_maps": "Maps"
}
- src/locales/es/map.json
{
"section_maps": "Mapas"
}
The generate_html fabric task will need to be run after a change to templates or data files:
$ fab generate_html
Fieldtrip open plugins allows projects to add functionality to the fieldtrip platform.
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.
All new pages added by a plugin should be created as templates in src/templates
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
}
});
Plugins can add a stylesheet by via javascript, e.g:
$('head').prepend('<link rel="stylesheet" href="plugins/<myplugin>/css/style.css" type="text/css" />');
For releasing the plugin you need to ensure the dependencies are first installed:
$ npm install
The default is to release incrementing the patch number:
$ npm run release
For minor/major:
$ npm run release minor
$ npm run release major
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
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": "."
}