Tag Syntax

Instantiating Tags

let element = <div.main> "Hello"var Imba = require('imba'), _1 = Imba.createElement; 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 Imba = require('imba'), _1 = Imba.createElement, 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 Imba = require('imba'), _1 = Imba.createElement; let state = "busy"; (_1('div').flag('header')).setFlag(0,state);

Setting inline styles

<div css:display='block' css:color='red'>var Imba = require('imba'), _1 = Imba.createElement; (_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 Imba = require('imba'), _1 = Imba.createElement, 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 t0, Imba = require('imba'), _1 = Imba.createElement; (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 t0, Imba = require('imba'), _2 = Imba.createTagList, _1 = Imba.createElement; (t0 = (t0=_1('ul'))).setContent((function tagLoop($0) { var 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 t0, Imba = require('imba'), _1 = Imba.createElement, 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 t0, Imba = require('imba'), _1 = Imba.createElement; 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 $ = 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 Imba = require('imba'), _1 = Imba.createElement; Imba.mount((t0 = (t0=_1('div')).setTemplate(function() { var $ = this.$, t0; return ($[0] || _1('span',$,0,t0).setText("Let's get started!")); })).end());