Deprecated

WebApp templates

WebApps use underscore templates. Templates are initially rendered server side and will be delivered to the client as HTML when the page loads. If the WebApp needs to be re-rendered, it will render client side using the same template. Templates are .html files stored in the /template folder.

Rendering a template

A component is responsible for setting a template. Either by using the template property or the getTemplate function.

template

Sets the template for the component.

getTemplate

Function for calculating which template to render

renderTemplate(template [, options])

Renders a template.

// using template property
define(function(require) {
   'use strict';

   var
      Component      = require('Component'),
      indexTemplate  = require('/template/index');

   return Component.extend({
      template: indexTemplate
   });
});  
// using getTemplate function
define(function(require) {
   'use strict';

   var
      Component     = require('Component'),
      listTemplate  = require('/template/list'),
      gridTemplate  = require('/template/grid');

   return Component.extend({
      getTemplate: function() {
         if (this.state.layout === 'list') {
            return listTemplate;
         }

         return gridTemplate;
      }
   });
});	

Rendering sub components

Rendering will always start from the template referenced in main.js. Most WebApps are split into different components and defining sub components is handled by the renderer.renderComponent function available in the template context.

renderer.renderComponent(componentName [, options])

Renders a sub component. componentName refers to the name of the component to render (the name of the file in the /component folder).

// template referenced from main.js
<h1>Hello from main template</h1>

// render a sub component
<%= renderer.renderComponent('MySubComponent') %>	

Rendering sub component with properties [@since 6.1]

When rendering sub components it is possible to pass properties to the component. Properties will be available on this.options and passed in as second parameter to filterState.

// render a sub component
<%= renderer.renderComponent('MySubComponent', {foo: 'bar'}) %>	
// MySubComponent.js
define(function(require) {
   'use strict';

   var Component = require('Component');

   return Component.extend({
      onRendered: function() {
         console.log(this.options.foo); // 'bar'
      },
            
      filterState: function(state, options) {
         // options -> {foo: 'bar'}
         return Object.assign({}, state);
      }
   });
});

Template context

A component's state (collected from the filterState function) is always available in the template context. Use underscore template syntax to print values.

// this.state.buttonText --> 'Click me!';
<button><%- buttonText %></button> // <button>Click me!</button>	

Template context may be extended using the templateFunctions helper for the rendering component.

templateFunctions (may be defined as a function)

Extend template context with custom functions and data.

define(function(require) {
   'use strict';

   var
      Component      = require('Component'),
      indexTemplate  = require('/template/index');

   return Component.extend({
      template: indexTemplate,
      
      templateFunctions: function() {
         return {
            foo: 'bar',
            getPrice: function(price, vatRate) {
               return price * vatRate;
            }
         };
      }
   });
});	
// index.html
<span><%- foo %></span> // bar
<span><%- getPrice(100, .25) %></span> // 25	

Methods

getUrl(path [, queryStringParameters])

Returns a WebApp specific url given a path. Pass an object as queryStringParameters to retrieve a url with given query string parameters.

// returns a URL that will match the /addToBasket path in index.js
<form action="<%= getUrl('/addToBasket') %>" method="post">
// ?sv.target=<id>&sv.<id>.route=/addToBasket

// update only query string
<a href="<%= getUrl('/', {layout: 'grid'}) %>"> 
// ?sv.target=<id>&sv.<id>.route=/&layout=grid	

getStandaloneUrl(path [, queryStringParameters]) [@since 4.5.5]

Returns a url that will execute a route standalone, i.e. it will not be part of page rendering. This is very useful when you only want to target your route without any side effects. Typical use cases are delivering a file from a route or redirecting when a form has been posted.

Below is an example demonstrating aforementioned use cases.

<form action="<%= getStandaloneUrl('/ship') %>" method="post">
   <input type="text" name="text">
   <button type="submit">Submit</button>
</form>

<a href="<%- getStandaloneUrl('/file') %>">Get file</a>
// index.js
router.post('/ship', (req, res) => {
	// Handling the posted form data in req.params...
	res.redirect('back');
});

router.get('/file', (req, res) => {
	const file = appData.getNode('file');
   
	res.sendFile(file);
});

getResourceUrl(path)

Returns a url to a resource within the WebApp's /resource folder.

<img src="<%- getResourceUrl('image.png') %>" />
/webapp-files/<webappname>/<webappversion>/image.png	

i18n(key [, varSubstitution...])

Returns localized string from bundles in the /i18n folder.

<h2><%- i18n('hello') %></h2>	

appContext.getWebAppNamespace(prefix)

Returns a prefixed unique namespace for the WebApp. Useful when there are several instances of the same WebApp on the same page.

<input id="<%- appContext.getWebAppNamespace('query') %>">