Tag Syntax

Instantiating Tags

let element = <div.main> "Hello"var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); let element = (_1('div').flag('main').setText("Hello"));

The above declaration might look strange at first. DOM elements are first-class citizens in Imba. We are creating a real dom element, with the className "main" and textContent "Hello".

Let's break down the basic syntax before we move on to more advanced examples. Since setting classes of elements is very common, imba has a special shorthand syntax for this. You declare classes by adding a bunch of .classname after the tag type. You can add multiple classes like <div.large.header.primary>. Can you guess how to set the id of a tag? It uses a similar syntax: <div#app.large.ready>.

Conditional Classes

One very common need when developing web apps is to set a className only when some condition is true. Imba has a shorthand syntax for this too:

# only add 'ready' class if expression is truthy <div.header .ready=expression>var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/), self = {}; // only add 'ready' class if expression is truthy (_1('div').flag('header')).flagIf('ready',self.expression());

Dynamic classes

What about setting fully dynamic classes? E.g. if state is a variable containing a string, you can set it like this;

let state = "busy" <div.header .{state}>var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); let state = "busy"; (_1('div').flag('header')).setFlag(0,state);

Setting inline styles

<div css:display='block' css:color='red'>var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); (_1('div').css('display','block').css('color','red')).end();

Setting custom data

When we move on to custom tags, you will find that tags very often represent some data.

<AppView[myData] title="Application">var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/), self = {}; (_1(AppView).setTitle("Application")).bindData(self,'myData',[]).end();

Rendering Lists

You might notice that we never close our tags. Rather than being delimited by curly braces or “begin/end” keywords, blocks are delimited by indentation, and so are tags. This might seem weird in the beginning, but it makes for very readable and concise code. So, if we want to create a list with some children, we simply go:

<ul> <li> "Understand indentation" <li> "Get used to it" <li> "Cherish it"var _t1, _t2, t0, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); (t0 = (t0=_1('ul')).setContent([ _1('li',t0.$,'A',t0).setText("Understand indentation"), _1('li',t0.$,'B',t0).setText("Get used to it"), _1('li',t0.$,'C',t0).setText("Cherish it") ],2));

If we have a dynamic list we can simply use a for in loop:

<ul> for activity in ["Eat", "Sleep", "Code"] <li> <span.name> activityvar _t1, t0, Imba = require('imba'), _2 = Imba.createTagList, _1 = Imba.createElementFactory(/*SCOPEID*/); (t0 = (t0=_1('ul'))).setContent((function tagLoop($0) { var _t2, _t3, t1; for (let i = 0, items = ["Eat","Sleep","Code"], len = $0.taglen = items.length; i < len; i++) { (t1 = $0[i] || (t1=_1('li',$0,i)).setContent(t1.$.A || _1('span',t1.$,'A',t1).flag('name'),2)).end(( t1.$.A.setContent(items[i],3) ,true)); };return $0; })(t0.$['A'] || _2(t0.$,'A')),4);

Conditional Rendering

<div> if isLoggedIn <a href="/logout"> "Log out" else <a href="/register"> "Register"var _t1, _t2, t0, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/), self = {}; (t0 = (t0=_1('div'))).setContent( self.isLoggedIn() ? ( (t0.$.A || _1('a',t0.$,'A',t0).setHref("/logout").setText("Log out")).end() ) : ( (t0.$.B || _1('a',t0.$,'B',t0).setHref("/register").setText("Register")).end() ) ,3);

Reactive Rendering

As we explain custom tags, you will learn that everything inside <self> is reactive by default. Ending a tag with -> or => instead of > marks it as reactive, and allows you to call render on the tag to re-render the content.

var number = 0 var dead = Imba.mount <div> <span> "Dead time is {Date.new.toLocaleString}" <span> "Number is {number}" var live = Imba.mount <div -> <span> "Live time is {Date.new.toLocaleString}" <span> "Number is {number}" setInterval(&,1000) do number++ dead.render # nothing changes live.render # content is updatedvar _t1, _t2, t0, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); var number = 0; var dead = Imba.mount((t0 = (t0=_1('div')).setContent([ _1('span',t0.$,'A',t0), _1('span',t0.$,'B',t0) ],2)).end(( t0.$.A.setText("Dead time is " + (new Date().toLocaleString())), t0.$.B.setText("Number is " + number) ,true))); var live = Imba.mount((t1 = (t1=_1('div'))).setTemplate(function() { var _t21, $ = this.$, t1; return Imba.static([ ($[0] || _1('span',$,0,t1)).setText("Live time is " + (new Date().toLocaleString())), ($[1] || _1('span',$,1,t1)).setText("Number is " + number) ],2,1); }).end()); setInterval(function() { number++; dead.render(); // nothing changes return live.render(); // content is updated },1000);

Rendering into document

To add tags to the actual document, you should use Imba.mount(element, into). If you do not supply a second argument, the element will be added to document.body by default.

Imba.mount <div -> <span> "Let's get started!"var _t1, Imba = require('imba'), _1 = Imba.createElementFactory(/*SCOPEID*/); Imba.mount((t0 = (t0=_1('div')).setTemplate(function() { var _t2, $ = this.$, t0; return ($[0] || _1('span',$,0,t0).setText("Let's get started!")); })).end());