Template functions
Directive "if"
Conditional render with "if".
eg.
<template>
<div>
<span if="this.name==='test'">name is test</span>
</div>
</template>
Tag "if"
Conditional flow with tag "if".
eg.
<template>
<if condition="this.name==='test'">
<span>name is test</span>
</if>
</template>
Tags "if" and "else"
eg.
<template>
<div>
<if condition="this.name==='test'">
<span>name is test</span>
<else>
<span>I dont know you!</span>
</else>
</if>
</div>
</template>
Tags "if" and "elseif"
eg.
<template>
<div>
<if condition="this.name==='test'">
<span>name is test</span>
<elseif condition="this.name==='test2'">
<span>ok, you are test2</span>
</elseif>
</if>
</div>
</template>
Tags "if","elseif" and "else"
eg.
<template>
<div>
<if condition="this.name==='test'">
<span>name is test</span>
<elseif condition="this.name==='test2'">
<span>ok, you are test2</span>
</elseif>
<else>
<span>I dont know you!</span>
</else>
</if>
</div>
</template>
Directive "each"
eg.
<template>
<ul>
<li each="item in this.itens">${item.name}</li>
</ul>
</template>
Directive "each" with a custom index
eg.
<template>
<ul>
<li each="item,$index in this.itens">${$index} - ${item.name}</li>
</ul>
</template>
Tag "for"
eg.
<template>
<ul>
<for each="item in this.itens">
<li>${item.name}</li>
</for>
</ul>
</template>
Tag "for" with index
eg.
<template>
<ul>
<for each="item,$index in this.itens">
<li>${$index} - ${item.name}</li>
</for>
</ul>
</template>
Directive "skip"
Conditional directive to avoid children rerender.
eg.
<template>
<div>
<span skip="this.name==='test'">name is test</span>
</div>
</template>
This is util when working with libs that dinamicaly insert itens into that node as select2, selectize and others.
Conditional attribute
eg.
<template>
<div>
<span>name is test</span>
<input type="checkbox" checked="${this.name=='test'}"/>
<input type="text" disable.if="this.maxPowerFool > 100"/>
<select>
<option value="1">one</option>
<option value="2" selected.if="this.myIndex === 2">two</option>
<option value="3">three</option>
</select>
</div>
</template>
Importing other module
eg.
<template>
<require from="./example/hello-world"/>
<div>
<h1>My First APP with ${this.title}</h1>
<hello-world name="C-3PO"/>
</div>
</template>
Giving an alias in module import statement
eg.
<template>
<require from="./example/hello-world as sea-bienvenido"/>
<div>
<h1>My First APP with ${this.title}</h1>
<sea-bienvenido name="C-3PO"/>
</div>
</template>
Import a css, less, scss, sass or styl file
You need "plugin-css" for jspm or equivalent if you are using requirejs or webpack.
eg.
<template>
<!--if using 'plugin-css' systemjs-->
<require from="./hello-world.css!"/>
<!--if using commons css plugins to requirejs-->
<require from="style!./hello-world"/>
<!--to others commons css plugins-->
<require from="css!./hello-world.css"/>
<!--to webpack loaders-->
<require from="./hello-world.css"/>
<!--to webpack "scss" loaders-->
<require from="./hello-world.scss"/>
<!--to webpack "styl" loaders-->
<require from="./hello-world.styl"/>
<h1>My First APP with ${this.title}</h1>
</template>
Embed a tag "style".
eg.
<template>
<style>
.especial-tag{
background-color:red;
}
</style>
<h1 class="especial-tag">
My First APP with ${this.title}
</h1>
</template>
Changing the css className
eg.
<template>
<h3 class="my-custom-classname">
My element with a custom className
</h3>
</template>
Changing the css className with expression
eg.
<template>
<h3 class="${'my-custom-classname '+this.customStyle}">
My element with a custom className by expression
</h3>
</template>
Tag "content"
Set where the content of element must be placed.
eg.
<!--hello-world.html-->
<template>
<h1>
<content/>
</h1>
</template>
Bellow is how "hello-world.html" will be used.
eg.
<template>
<require from="./example/hello-world"/>
<div>
<hello-world>
Good night!
</hello-world>
</div>
</template>
Importing/using other library/script
eg.
<template>
<require from="moment" type="script"/>
<span>${moment().format('DD/MM/YYYY')}</span>
</template>
Using a ui library with namespace
It is a basic example, but there are a more elaborate implementation at twbs-hgo.
eg. of usage
<template>
<require from="ui-vendor as ui" type="namespace"/>
<div>
<span>using a ui library</span>
<ui:progress-bar/>
</div>
</template>
Creating a ui library with namespace
eg. creation
// ui/index.js
import progressBar from './progress-bar/progress-bar.html'; // .html will be .html.js
export { progressBar }; // progressBar will be used as ui:progress-bar
When working with typescript you will need to create a ".html.d.ts" file to represent a valid import, with these content:
// ui/progress-bar/progress-bar.html.d.ts
declare let obj:{};
export default obj;
Using a custom directive with namespace
It is a basic example, but you can create your own directive to format html text contents.
eg. of usage
<template>
<require from="ui-vendor as d" type="namespace"/>
<div>
<span>using a ui library</span>
<span d:upper-case>This directive change all text to UPPERCASE this text!</span>
<span d:upper-case="test">This directive will replace only test to TEST in this text!</span>
</div>
</template>
Creating a ui library with namespace
eg. creation
// ui/upper-case/upper-case
export const upperCase = (p_node: Node, p_value: string) => {
if(p_value){
p_node.nodeValue = p_node.nodeValue.replace(new RegExp(p_value,'g'), p1 => {
return p1.toUpperCase();
});
}else{
p_node.nodeValue = p_node.nodeValue.toUpperCase();
}
}
eg. exporting
// ui/index.js
import { upperCase } from './upper-case/upper-case'; //
export { upperCase }; // upperCase will be used as ui:upper-case
Limitations
A custom directive actually must be used to replace and format innerText of basic html tags and not to format it's appearance or change it's behavior. A good approach is to use the shortcut of libraries as momentjs or i18n.
Attribute "key:id"
When using attribute "key:id" the element instance will be preserved.
eg.
<template>
<require from="./test-comp"/>
<div>
<for each="item in this.itens">
<test-comp key:id="${item.id}"/>
</for>
</div>
</template>
You shouldnt use this every moment, but it is recomended to use in a interation with tag "for".
Directive "trigger"
This will associate a controller method to DOM event.
eg.
<template>
<button click.trigger="this.showName">show my name!</button>
</template>
Directive "trigger" with paramaters
This will associate a controller method to DOM event with paramaters.
eg.
<template>
<button click.trigger="this.showName('test')">show my name!</button>
</template>
CamelCase method or attribute
To access a camelCase method or attribute from template use slashes '-'.
eg.
<template>
<require from="./test-comp"/>
<div>
<test-comp full-name="test"/>
</div>
</template>
Event emitter
You can use 'event-emitter-lite' which has a good integraction with ferrugemjs so when component is detached ferrugemjs call his 'unsubscribeAll' method automatically. If you need a aproach more complex please use 'v3rtigo'.
eg.
<template>
<require from="./test-comp"/>
<div>
<test-comp on-change-name.subscribe="this.receiveNameFromChild"/>
</div>
</template>
eg.
// test-comp.js
import { EventEmitter } from 'event-emitter-lite';
export class TestComp{
constructor(){
this.onChangeName = new EventEmitter();
setTimeout(() => {
this.onChangeName.emit('Noise!!!!');
}, 4000);
}
}
Tag "composition"
With composition you need use "view:from" to load the view.
eg.
<template>
<div>
<compose view:from="path_to_dinamic_module/module_to_loader"/>
</div>
</template>
Template "model" attribute
eg.
<!--view-one.html-->
<template model="./universal-view-model">
<div>
<h1>VIEW ONE</h1>
<span>bla,bla,bla....</span>
</div>
</template>
Template "no-model" attribute
Template viewmodel-less with "no-model" attribute.
eg.
<template no-model>
<h1>NO viewmodel</h1>
</template>
Template "no-model" attribute and with a init script
Template viewmodel-less with "no-model" attribute might have a init script as it constructor.
eg.
<template no-model>
<div>
<script type="text/javascript" init="init">
function init({title}){
this.loaded = true;
this.title = title;
}
</script>
</div>
<h1>NO viewmodel</h1>
</template>
Function representation
If you have a function with a "export default" you can represent it in your template with a tag.
eg.
export default function(log){
console.log(log);
}
Using
<template>
<require from="./myfunctionlog as fn-log" type="script"/>
<div>
<fn-log msg="it is alive"/>
</div>
</template>
Other example
//make your own router interface
import page = require("page");
export default (config:{path:string,setHandler:Function})=>{
if(config.path && config.setHandler){
page(config.path,context=>{
config.setHandler(context.params);
});
}else{
page.start();
}
}
Using
<template>
<require from="../commons/router as add-router" type="script"/>
<div>
<add-router path="/user/:id" set-handler="this.edit"/>
</div>
</template>
Tag "script"
Useful when working with some jquery plugins.
eg.
<template>
<require from="jquery as jq" type="script"/>
<div>
<span class="test"></span>
<script>
jq(".test").hide();
</script>
</div>
</template>
Conditional script
eg.
<template>
<require from="jquery as jq" type="script"/>
<div>
<span class="test"></span>
<script if="!this.hidden">
jq(".test").hide();
</script>
</div>
</template>
Scope of a component into "script" tag
Into a "script" tag the "this" scope is first attributed to component scope.
eg.
<template>
<require from="jquery as jq" type="script"/>
<div>
<span class="test"></span>
<script if="!this.hidden">
jq(".test").hide();
this.hidden = true;
</script>
</div>
</template>
Tag refresh
eg.
<template>
<div>
<span>${this.inc}</span>
<refresh if="this.inc === 1" inc="${2}"/>
</div>
</template>
Warning, be cauteloso to use this functionality to avoid freezing your component. So prefer using "refresh tag" with "if" condition and changing property value to skip previous condition as below:
<refresh if="this.inc === 1" inc="${2}"/>