Apps

The app folder

Different configurations are structured in apps. A typical app is structured as follows:

App folder structure
<apps-folder>
\- <app-folder>                   // name of the app
    +- nls                      // i18n directory, see dojo i18n (optional)
    |   +- de                   //  German i18n resource directory
    |   |   \-bundle.js         //  German i18n resource file
    |   \- bundle.js            // root i18n resource file (en)
    |
    +- app.json                 // app configuration(required)
    |
    +- app.js                   // optional .js file to load custom scripts
    |
    +- app.css                  // optional css rules, which can overwrite template and theme rules (optional)
    |
    + <anysubdirectory and any other resource>  // you can put into an app folder any resource
                                                // also bundles, templates and themes

The app.json file is the only file required within an app folder and explained in the next section.

The i18n system works the same as for bundles. See the bundle internationalization section for details.

In old versions it was required to load the i18n files via the app.js. This is not longer required.

The optional file app.css can contain extra CSS rules.

Increase the specificity of the CSS selector by at least one. For example use .ctAppRoot in combination with the template (for example .ctTpl_seasons) or theme class (for example .everlasting). This way the selector has the strength to overwrite existing layout definitions. By using .ctAppRoot you prevent unwanted side effects, because the layout definitions are only effective inside the map.apps app.
app.css
.ctAppRoot.ctTpl_seasons .map_main .search-ui {
    width: 500px;
}

As mentioned earlier, an app folder can also contain templates, themes, and bundles.

Use app-relative resource paths

Very often bundles need the configuration of external or application-specific resources, like image URLs or links to backend services. The ${app} expression, which occurs in some of the preceding samples, is used to achieve this goal.

The ${app} expression is evaluated by the ConfigLocator, which changes this placeholder to an AMD package prefix. The general pattern is <configlocation>/<appname>. In most project deployments, it is converted to apps/<appname>. For apps created with the map.apps Manager the replacement looks like this: builderapps/<appname>. The second example demonstrates that this is not a relative URL to a special path, because a builderapps path does not exist anywhere. Instead, the AMD prefixes are registered by the index.html (or dojo-init.js), so that the global AMD method require can be used to build full URLs.

Whether the use of ${app} is sufficient to generate a correct app relative URL depends on the bundle implementation.

If a bundle uses the methods Bundle.getResourceURL, ComponentContext.getResourceURL or resourceURL of ct/_url, use the following style:

app relative resources
{
  ...,

  "bundles" : {
    "mybundle": {
      "MyComponent":{
      // pattern is: "${app}:<path>/<file>"
      "url": "${app}:images/test.png"
    }
  }
}

The : (colon) is the separator between AMD package and the resource, relative to this package. This declaration style allows to point to any resource in any bundle if the namespace of the bundle is used instead of ${app}. for example the prefix ct/bundles/map points to any resource inside the map bundle. This mechanism provides the ability to point to external or server stable URLs, if the prefixes are registered. It also allows the definition of resource bundles (bundles which only contain special resources).

If the direct use of ${app} fails, for example because a bundle does not use the methods listed earlier to build resource URLs, the configuration mechanism provides an additional way: "resource" expressions. A resource expression looks like this:

app.json resource expressions
{
  ...,
  "bundles" : {
    "mybundle": {
      "MyComponent":{
        "url": "resource('${app}:images/test.png')"
      }
    }
  }
}

The resource expressions are evaluated in the context of the bundle, which evaluates the configuration. Internally the Bundle.getResourceURL method is used. Here are some examples:

Sample Sample URL Description

"resource( '${app}:images/test.png')"

http://localhost:8080/js/apps/sample/images/test.png

${app} resolves to apps/sample.

apps is registered as AMD prefix pointing to http://localhost:8080/js/apps.

"resource( 'images/test.png')"

http://localhost:8080/js/bundles/mapcore/map/images/test.png

The resource expression is evaluated in the context of the map bundle and this is located in http://localhost:8080/js/bundles/mapcore/map.

"resource( 'images/test.png')"

http://localhost:8080/js/bundles/base/splashscreen/images/test.png

The resource expression is evaluated in the context of the splashscreen bundle and this is located in http://localhost:8080/js/bundles/base/splashscreen.

This sample demonstrates that — without a module prefix —  the context is important!

"resource( 'templates:images/test.png')"

http://localhost:8080/js/bundles/base/templates/images/test.png

The resource expression uses the AMD package name of the templates bundle (the namespace) and points to this bundle, which is located in http://localhost:8080/js/bundles/base/templates.

Resource expressions help to create correct URLs in most cases.