idomizer
v1.0.2
Published
An HTML template compiler providing an incremental-dom render factory.
Downloads
32
Maintainers
Readme
idomizer
idomizer
is an HTML template compiler providing an incremental-dom render factory.
idomizer
can be used at compile time (front end projects) or runtime time(back end projects).
Versions and compatibilities:
- idomizer <= 0.5 -> incremental-dom 0.4 and below.
- idomizer >= 0.6 -> incremental-dom 0.5 and above.
- idomizer >= 1.0.0 -> incremental-dom 0.6 and above.
Installation
$ npm install idomizer
<script src="https://ajax.googleapis.com/ajax/libs/incrementaldom/0.6.0/incremental-dom-min.js"></script>
<script src="https://unpkg.com/idomizer/dist/idomizer.min.js"></script>
<script>
var factory = idomizer.compile('<h1>Hello!</h1>');
var render = factory(IncrementalDOM);
IncrementalDOM.patch(document.body, render);
</script>
Babel
A babel's plugin is available to compile an idomizer template into an incremental-dom render factory.
See the babel's plugins page to get more information about plugins in babel.
{
plugins: ['idomizer/lib/plugins/babel-idomizer.js']
}
Presently the plugin only support ES6 Template literals tagged with idomizer.
For instance,
const template = idomizer`<h1 class="{{data.h1Class}}">Hello</h1>`;
will be compiled into:
var template = function (_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('h1', null, null, 'class', data.h1Class);
_text('Hello');
_elementClose('h1');
};
};
Be aware the template can not contain expressions like ${anExpression}
.
Webpack
A webpack's loader is available to compile an idomizer file into an incremental-dom render factory.
See module.rules to get more information about loaders in webpack.
module.loaders: [
{test: /\.idomizer$/, loader: 'idomizer/lib/plugins/idomizer-loader'}
];
Browserify
A browserify's transform module is available to compile an idomizer file into an incremental-dom render factory.
See transforms to get more information about the transform system in browserify.
browserify -t idomizer/lib/plugins/idomizerify main.js > bundle.js
const browserify = require('browserify');
const idomizerify = require('idomizer/lib/plugins/idomizerify');
const bundle = browserify();
bundle.transform({ extension: 'html' }, idomizerify);
API
idomizer.compile
transforms an HTML template into a factory method.
// idomizer.compile('<h1 class="main">Hello</h1>') will return:
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('h1', null, ['class', 'main'], null);
_text('Hello');
_elementClose('h1');
};
}
The factory method requires the incremental-dom library and an optional map of helpers. The factory returns the incremental-dom's render method.
Syntax
Static attributes
From
idomizer.compile(`<h1 class="main">Hello</h1>`)(IncrementalDOM);
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('h1', null, ['class', 'main'], null);
_text('Hello');
_elementClose('h1');
};
}
Dynamic attributes
From
idomizer.compile(`<h1 class="{{data.h1Class}}">Hello</h1>`)(IncrementalDOM)
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('h1', null, null, 'class', (data.h1Class));
_text('Hello');
_elementClose('h1');
};
}
Self closing elements
From
idomizer.compile(`<input type="text" value="{{data.value}}">`)(IncrementalDOM)
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementVoid('input', null, ['type', 'text'], 'value', (data.value));
};
}
Dynamic text nodes
From
idomizer.compile(`<strong><tpl-text value="data.value"/></strong>`)(IncrementalDOM)
// or
idomizer.compile(`<strong>{{ data.value }}</strong>`)(IncrementalDOM)
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('strong', null, null, null);
_text(data.value);
_elementClose('strong');
};
}
Condition with the tags if, else-if and else
From
idomizer.compile(`
<tpl-if expression="data.yes">
YES!
<tpl-else-if expression="data.yes !== false" />
MAY BE!
<tpl-else/>
NO!
</tpl-if>
`)(IncrementalDOM);
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
if (data.yes) {
_text('YES!');
} else if (data.yes !== false) {
_text('MAY BE!');
} else {
_text('NO!');
}
};
}
Iteration with the tag each
From
idomizer.compile(`
<tpl-each items="data.items">
<strong tpl-key="{{index}}">
<tpl-text value="index"/>-<tpl-text value="item"/>
</strong>
</tpl-each>
`)(IncrementalDOM);
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
(data.items || []).forEach(function (item, index) {
_elementOpen('strong', (index), null, null);
_text(index);
_text('-');
_text(item);
_elementClose('strong');
});
};
}
Iteration with inline javascript
From
idomizer.compile(`
[[ data.items.forEach(function (item, i) { ]]
<strong tpl-key="{{i}}">
<tpl-text value="i"/>-<tpl-text value="item"/>
</strong>
[[ }); ]]
`)(IncrementalDOM);
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
data.items.forEach(function (item, i) {
_elementOpen('strong', (i), null, null);
_text(i);
_text('-');
_text(item);
_elementClose('strong');
});
};
}
Custom tags
From
idomizer.compile(`<strong>strong text</strong><x-test></x-test><strong>strong text</strong>`, {
tags: {
'x-test': {
onopentag(name, attrs, key, statics, varArgs, options) {
return `t('${name} element');`;
}
}
}
})(IncrementalDOM);
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('strong', null, null, null);
_text('strong text');
_elementClose('strong');
_text('x-test element');
_elementOpen('strong', null, null, null);
_text('strong text');
_elementClose('strong');
};
}
Custom helpers
From
const subRender = compile(`helper content`)(IncrementalDOM);
idomizer.compile(`
<strong>strong text</strong>
<tpl-call name="subRender" />
<strong>strong text</strong>
`)(IncrementalDOM, {subRender});
To
function template(_i, _h) {
var _elementOpen = _i.elementOpen,
_elementClose = _i.elementClose,
_elementVoid = _i.elementVoid,
_text = _i.text,
_skip = _i.skip;
return function (_data_) {
var helpers = _h || {},
data = _data_ || {};
_elementOpen('strong', null, null, null);
_text('strong text');
_elementClose('strong');
helpers.subRender(data);
_elementOpen('strong', null, null, null);
_text('strong text');
_elementClose('strong');
};
}
Custom elements
For incremental-dom, custom elements are regular HTML elements.
So, if a custom element generates a sub-tree (i.e. a light DOM) outside of a ShadowDOM node,
it will be overridden during the execution of the function patch()
.
To control this default behavior, incremental-dom provides the function skip()
saying:
don't touch the inner light DOM of the just opened node!
By default idomizier detects the custom elements and force the call of the function skip()
to protect their light DOM nodes.
Custom elements are detected according to the following rules:
- from the name, because of the
-
character - from the attribute
ìs
Obviously, this behavior can be deactivated:
- globally (for a whole HTML template)
const render = compile(`<x-element><p>will part of the light DOM</p></x-element>`, {skipCustomElements : false})
- locally (an HTML element), ``
const render = compile(`<x-element tpl-skip="deactivated"><p>will part of the light DOM</p></x-element>`)