Command Reference

Overview

ourthings has two formats for interacting with your templates. One is a traditional approach that will be familair to users fo existing templating libraries such a mostache and jsrender and the second and more powerful queue system that is unique to ourthings. We refer to them as template *tags* and *queueables*.

Queuables

Queueables are javascript modules that can be called from inside your templates to perform a wide range of functions. This can range from changing the class of an element in the page to making a rest API call or moving a map around.

The simplist invocation and possibly the most frequent used example is that of rendering a template to the DOM.

@templates.render({"targetId":"#content","template":"#basic"},{"queueRun":"Instant"});

Breaking this down the command format is defined as

@queueable.command(arguments,options);

If you are familar with the javascript OO model then queueable.command() will already be very familar to you and you can translate that to directly running a function in javascript from the html page. queueables are very much built in this fashion by extending a class and writing functions. We also want to pass arguments to that function and you do this by sending some json in which the function will be given.

Options are things you want to instruct the queue handler to do with this item in the queue. This can range from delaying execution, running instantly or waiting for the user to hit a button see the command options sections for a list of these

Command Options

Queues are lists of all these commands that are run in sequence. The @ indicates the start of a list and - indicates the children of that queue, IE commands that will be run subsequently. Each command only executes after successful execution of the previous command and memory by default is maintained while the queue is running so each command has access to anything the previous command may have set. This can be over written by the memoryMode setting to make it available to other queues or make the data permanent

Memory

To understand how memory works take this example

@api.post({"url":"https://loginapi.com","body":{"token":"{{!memory.token.value}}"},{"memoryMode":"Session","memoryName":"sessionAPI"});
-internals.ifqueue({"statement":"memory.sessionAPI.value.API.Code!==200","name":"loggedOut"});

@browser.redirect({"location":"index.html"},{"queuePrepare":"loggedOut"});

Here we call a login api as soon as the page loads and send it the value {{!memory.token.value}} to check we have a valid token. The API response is loaded into memory where we have defined "memoryMode":"Session","memoryName":"sessionAPI". How does that token value exist as we just loaded the page? When we logged in previously we set that value to be permanent using:

-internals.setMemory({"name":"token","value":"{{!memory.sessionAPI.value.API.token}}","mode":"Permanent"});

The internals.ifqueue checks the API to see if we have a valid session. If we don't we run a prepared queue that will redirect us to the login page

Prepared queues

Prepared queues are 'things' we want to do at some later stage, possibly called from multiple locations or as the result of events. In the above example we used a simple one to logout as user by redirecting them another page. We might want to call that for a lot of places and while its only one command in practice we probably want to warn the user and do a host of other stuff so we group the commands up and call them, think of it like a function call

<!-- Make a descision to call a prepared queue -->
@internals.ifqueue({"statement":"memory.sessionAPI.value.API.Code!==200","name":"loggedOut"});

<!-- Just call a queue -->
@internals.execute({"name":"loggedOut"});

<!-- Our prepared queue -->
@browser.redirect({"location":"index.html"},{"queuePrepare":"loggedOut"});

Template Commands

{{}} & {{!}} & {{!^}}

Ourthings supports a standard template of {{something}} that allows the execution of javascript to place values in the page. This format can used in two ways.

1. Placing values in a rendered template at render time EG {{memory.foo}} will output the value window.foo

2. Passing values to argument lists in queueables at command execution time using {{!memory.foo}}

Its important to understand when you need to use {{}} and {{!}}. If you are simply displaying data in a template use {{}}. This is because when that template is shown to the user you want the value it represents at that time. If however you have a queue and the last item in that queue depends on a value that may change as a result of that queues preceding commands (EG an api call) then you want {{!}}. The variant {{!^}} can be used to remove surrounding quotes when injecting JSON into JSON for example

@api.post({"url":"{{config.api}}api/","body":{"_token":"{{!memory.token.value}}","schema":"{{!memory.sub.value}}","app":"boundary","api":"reporting_api","action":"run_report","payload":{"report_name": "set_system_config","_param_1":"{{!^JSON.stringify(memory.configAPI.value.API.Response.system_config)}}"}}});

Without the {{!^}} the JSON that is being inserted to the JSON string would be quoted causing a parsing error. The above example contains correct usage of all formats. {{config.api}} - This never changes so we can render at template render time. {{!memory.token.value}} - This value can change at any time, "{{!^JSON.stringify(memory.configAPI.value.API.Response.system_config)}}" - will produce JSON so we need to remove the ""

Both type of template commands are not supported in the root document. IE if you have an index.html you can not use any template commands in there. This is because the browser will have rendered the page before the framework is online and so depending on load speed there would be a period of time where these template commands could be visible to the user and cause a pop-in affect. Through development of previous version where we did allow this we found it caused bad practice in app creation or the need for loading animations which is generally not good practice. The developer should consider the root document as what the user/bot will first see and then build out dynamic content using the init command queue which is executed when the browser has finished loading all content. the system is online

{{#include [#template]}}

If you want to include a template (normally for reuse purposes) into the template you using then use {{#include}}.
<script id="myTemplayeId" type="text/html">
	blah
</script>

{{#include '#myTemplayeId'}}

This would result in 'blah' replacing {{#include #myTemplayeId}}

{{#for [variable]}}

Loop though an array or object. There are two ways of inserting the index, the quick and dirty #loop0 which will only work if used directly inside the template and {{memory.for0.value.index}} which will work in subsequent templates that are for example included with {{#include}} inside the loop

{{#for memory.people.value}}
  {{memory.people.value[#loop0].name}}
{{/for}}

{{#if [test]}}

Perform a if
{{#if memory.people.value.length>0}}
	There are people
{{else}}
	There are not any people
{{/if}}

templates.json

When you include your ourthings build by default the file templates.json will be loaded. You may specify a different json file to use if you have more than one build. This is useful if you have for example a login page which only needs a few functions

<script type="text/javascript" src="dist/login.bundle.js" data-templates="templates-login.json"></script>

The json file is an array of template files to include

[
  "templates/login/actions.html"
]

If you need to include css use the object format

[
	"templates/login/actions.html",
	{
		url:"css/mycss.css",
		type:"text/css"
	}
]

To produce unique builds you can use a webpack config like this

const path = require('path');
module.exports = {
	mode: 'development',
	entry: {
		full:'./src/digitalboundary/index.js',
		login:'./src/digitalboundary/login.js'
	},
	output: {
		filename: '[name].bundle.js',
		path: path.resolve(__dirname, 'site/dist')
	}
};

index.js would contain imports for all the libs you need where as login.js will just be a subset