Skip to main content

MC Template Engine

MotorCortex provides a built-in Template Engine to serve the templating of html and css props of Clips.

MotorCortex's Template Engine:

  • Does not use eval neither new Function, making it safe from code injection
  • Supports exactly two structural directives:
    • loop (mc-for)
    • condition (mc-if)
  • Supports value rendering

In case of HTML, the MC Template Engine demands the provided template to have a single root element that can (of course) contain any HTML code.

Wrong

<div class="alpha">
<span>This template won't pass</span>
</div>
<div class="alpha">
<span>as it contains two (and not just one) elements</span>
</div>
<div>
<div class="alpha">
<span>This template is fine</span>
</div>
<div class="alpha">
<span>as it contains a single element</span>
</div>
</div>

Value rendering

Value rendering is straightforward by the use of double curly brackets:

  • {{ attrs.x }}
  • {{ attrs.y[3] }}
  • {{ initParams.x - initParams.y }}
  • {{ initParams.x + '_string' }}
  • etc

Caution: When working with strings use single quotes.

Wrong

{
{
"string" + initParams.stringOne;
}
}

Right

{
{
"string" + initParams.stringOne;
}
}

Value rendering can be used both on HTML and CSS on Clip's properties.

Structural Directives

Structural Directives can only be used on the HTML of Clips (not on CSS) as they are defined as HTML elements' attributes (mc-for / mc-of and mc-if).

Loop

MC Template Engine gives the ability to iterate on any array or object and on each circle you can refer to both the key (either 0,1,2,... for arrays or object keys for objects) and the value.

Example

Let's get as an example a Clip that has got on its props.initParams the object:

{
items: [
{
name: "Cat",
description: "An animal with billions of videos on Facebook",
},
{
name: "Dog",
description: "Human's best friend",
},
];
}

Then this html template:

<div id="root">
<div class="looper" mc-for="key,item" mc-of="initParams.items">
<span class="{{ 'class_' + key }}"
>{{ item.name }}: {{ item.description }}</span
>
</div>
</div>

will be rendered as:

<div id="root">
<div class="looper">
<span class="class_0"
>Cat: An animal with billions of videos on Facebook</span
>
</div>
<div class="looper">
<span class="class_1">Dog: Human's best friend</span>
</div>
</div>

Please notice that the looped element needs to define two attributes: mc-for and mc-of.

mc-for

mc-for expects as its value a comma separated pair or keywords that will refer on the key and the value of each iteration.

mc-of

mc-of's value defines either:

  • an array
  • an object
  • a string
  • an integer In the case of an object or an array the iteration will be executed on its key/value pairs.

In the case of a string the iteration will be executed on its characters while in the case of an integer the engine will just iterate as many times as the provided integer.

Condition

The structural directive mc-if allows the developers to apply conditional rendering of elements.

Example

Let's get as an example a Clip that has got on its props.initParams the object:

{
conditionOne: true,
conditionTwo: false,
numberOne: 3,
numberTwo: 4,
stringOne: "alpha",
stringTwo: "alpha-beta"
}

The following template:

<div>
<div mc-if="initParams.conditionOne">This should render (1)</div>
<div mc-if="initParams.conditionTwo">This should not render</div>
<div mc-if="initParams.numberOne === initParams.numberTwo - 1">
This should render (2)
</div>
<div mc-if="initParams.numberOne === initParams.numberTwo">
This should not render
</div>
<div mc-if="initParams.stringOne + '-beta' === initParams.stringTwo">
This should render (3)
</div>
<div mc-if="initParams.stringOne === initParams.stringTwo">
This should not render
</div>
</div>

will be rendered as:

<div>
<div>This should render (1)</div>
<div>This should render (2)</div>
<div>This should render (3)</div>
</div>

Caution: When working with strings in the mc-if value always use single quotes.

Wrong

<div mc-if='"string" + initParams.stringOne'>
This is wrong and won't render
</div>

Right

<div mc-if="'string' + initParams.stringOne">
This is right and it'll render correctly
</div>