eoraptor.js
A mini expression javascript template engine without any dependence. Compatible with client-side and server-side.
Features
- Cleaner grammer than
mustache
. - Without
with
statement in compiled function, recognized performance problems will be shielded. - More detailed error logging.
- Build-in
index
support when iterating an array. - Build-in
else if
support. - TODO: Customizable output filter plugin.
- More useful partial template than
mustache
. - Matching eoraptor-jst tool in npm package.
Unit test
A quick glance at the unit test maybe the most direct way to dive in.
Usage
Client-side
Including the eoraptor engine by script tag.
<script src="path/to/eoraptor.min.js"></script>
The classic hello world
example achieved through a variety of ways.
Method 1:Compiling a template from a string parameter.
var hw = eoraptor.compile("Hello {{=name}}!");
hw({"name": "world"});
Usually, this method is more suitable for compiling a pretty simple template.
Method 2:Compiling templates from the script tags, with a text/x-eoraptor
type and an unique id
property.
<script type="text/x-eoraptor" id="hw">
Hello {{=name}}!
</script>
<script>
eoraptor.extract();
eoraptor.hw({"name": "world"});
</script>
Method 3: Including the precompiled file which contains all template functions and rendering directly without callingeoraptor.compile()
or exraptor.extract()
api.
<script src="path/to/eoraptor-precompiled.js"></script>
<script>
eoraptor.hw({"name": "world"});
</script>
</html>
The name of eoraptor-precompiled.js
file and the namespace of all templaltes,eoraptor
in the example above, would be any other word as you like(a declaration in options of pre-compiling tool), and the content in the file would look like this:
(function () {
var ns = this["namespaceYouLike"] || {};
ns["hw"] = function (data){
var t__ = data, r__ = [];
r__.push("Hello ");
r__.push(t__.name);
r__.push("!");
return r__.join("");
};
});
NOTE: The reality of namespace declaration
would be more complex than here, more details will be found in pre-compiling section.
API
Compiling and caching a template
eoraptor.compile(template)
/ eoraptor.compile(id, template)
- template: the template string.
- id: a unique name will be used as the
key
for inner cache. If none, the template
itself will be used instead.
In order to improve the performance of compiling, this method will save a cache for every template string, when the same template is passed in, it will skip the parsing step and return the cache directly.
The method returns a compiled renderable
function with two properties, the render
property is a reference to the function itself which takes one parameter as the context data. The source
property is only the string form of the render
, used by the pre-compile tool.
Demo:
var fooTpl = eoraptor.compile('foo','{{=foo}}');
fooTpl.render(data);
fooTpl(data);
eoraptor.foo(data);
Compiling templates from script tags
eoraptor.extract()
All script tags with a "text/x-eoraptor" type and an unique id property will be processed as individual template definitions.
Demo:
<script id="sayMorning" type="text/x-eoraptor">
Good morning, {{=name}}!
</script>
<script id="sayAfternoon" type="text/x-eoraptor">
Good afternoon, {{=name}}!
</script>
<script type="text/javascript">
eoraptor.extract();
typeof eoraptor.sayMorning;
typeof eoraptor.sayAfternoon;
</script>
After calling the extract
, the script tag will be added a compiled
attribute, so it would be ignored in next calling.
<script id="sayMorning" type="text/x-eoraptor" compiled="1">
Good morning, {{=name}}!
</script>
Setting delimeter
eoraptor.setDelimeter(start, end)
- start: optional, the start flag for delimeter, default to '{{'.
- end: optional, the start flag for delimeter, default to '}}'.
Demo:
eoraptor.setDelimiter('<%', '%>');
var tpl = eoraptor.compile('<%this.name%>');
tpl({"name": "eoraptor.js"});
Template
variable(html-escaped by default)
{{=key}}
/ {{=["key"]}}
- key: required, the direct value of the
key
in context data.
Under the hood, the function returned by eoraptor.compile()
is builded without with
statement, so it will not throw errors like underscore
.
Demo: output the value of the key
in context data.
var tpl = eoraptor.compile("{{=name}}");
tpl.render({"name": "<h1>eoraptor.js</h1>"});
Demo: if there is no such key
in context data.
var tpl = eoraptor.compile("{{this.name}}");
tpl.render({});
un-escaped variable:
{{-key}}
/ {{-["key"]}}
- key: required, the direct value of the
key
in context data.
demo: output the un-escaped value of the key
in context data.
var tpl = eoraptor.compile("{{@this.name}}");
tpl.render({"name": "<h1> eoraptor.js </h1>"});
if block: comparing by ==
.
START with: {{?key}}
/ {{?["key"]}}
- key: required, the direct value of the
key
in context data.
END with: {{/}}
Demo: To determine whether the if()
is like true
, comparing by ==
..
var data = {"foo": 1};
var tpl = eoraptor.compile("{{?foo}}like true{{/}}");
tpl.render(data);
Demo: To determine whether the if()
is true
, comparing by ===
.
var data = {
"foo": 1,
"fooIsTrue": function () {
return this.foo === true;
}
};
var tpl = eoraptor.compile("{{?fooIsTrue}}is true{{/}}");
tpl.render(data);
else if block:
START with: {{^anyValue}}
/ {{^this.key}}
/ {{^this["key"]}}
/ {{^anyValue vs anyValue}}
- anyValue: any value of any types like
foo
, true
, []
, {}
, etc. - key: the direct value of the
key
in context data. - vs: available comparation flags contains
==
, ===
, !=
, !==
, >=
, <=
, >
, <
END with: {{/}}
Demo:
var tpl = eoraptor.compile("the number is {{#this.number === 1}}"+
"one"+
"{{^this.number === 2}}"+
"two"+
"{{/}}");
tpl.render({"number": 2});
else block:
START with: {{^}}
END with: {{/}}
Demo:
var tpl = eoraptor.compile("the number is {{#this.number === 1}}"+
"one"+
"{{^}}"+
"unknown"+
"{{/}}");
tpl.render({});
iteration block:
{{#this.key currentItem[ currentKey]}}
- key: required, the direct value of the
key
in context data. - currentItem: required, assign a variable to represent the current item in an iterative process.
- currentKey: optional, default to
k__
, assign a variable to represent the current key in an iterative process. It will be a number
value(like 0, 1, 2, etc.) or a string
value determined by the iterative object, say, array
or object
.
Demo: traversal of an array
var data = {
name: "eoraptor",
features: [
"simple",
"standalone"
]
};
var tpl = eoraptor.compile("<ul>"+
"{{#this.features item key}}"+
"<li>{{key}}. {{this.name}} is {{item}}</li>"+
"{{/}}"+
"</ul>");
tpl.render(data);
Demo: enumerating an object
var data = {
features: {
"grammer": "simple",
"dependency": "standalone"
}
};
var tpl = eoraptor.compile("<ul>"+
"{{#this.features item key}}"+
"<li>{{key}}:{{item}}</li>"+
"{{/}}"+
"</ul>");
tpl.render(data);
{{!comment}}
- comment, any word for the commit.
Demo:
var tpl = eoraptor.compile("{{!hello}}eoraptor.js");
tpl.render();
end of a block
{{/}}
You can see it everywhere above.
partial template
{{>partialName[ partialContext]}}
- partialName: required, the name of partial template
- partialContext: optional, the data context for partial template function
Most of time, each UI compontent in the page is coded by several people, and everyone has the responsibility to keep their code clean, so the key
in the partial template may be the same as each other. As you will see in the code lower, both templates, navi
and slider
, have the list
key, so it will not work correctly with a public context data.
Unless changing list
into naviList
and sliderList
, but it's clearly violates the reused principle.
At this time, we can resolve the key
conflict by assignasing an independent context data to partial template when defining a combined one.
Compiling two partial templates for later use, say navi
and slider
:
eoraptor.compile('navi', '<ul>{{#this.list item}}'+
'<li>{{item.text}}</li>'+
'{{/}}</ul>');
eoraptor.compile('slider', '<ul>{{#this.list item}}'+
'<li>{{item.img}}</li>'+
'{{/}}</ul>');
Below we compile and render a combined template, including two partial templates defined above.
var tpl = eoraptor.compile(
'<p>navi:</p>'+
'{{>navi this.navi}}'+
'<p>slider:</p>'+
'{{>slider this.slider}}'
);
tpl.render({
navi: {
list: [
{text: 'foo'}, {text: 'boo'}
]
},
slider: {
list: [
{img: '1.jpg'}, {img: '2.jpg'}
]
}
});
License
The JavaScript Templates script is released under the MIT license.
Author
@gnosaij / www.joy-studio.com
Changelog
- 2014-04-15
compile
method support zero parameter- update grunt task
- 2014-04-03
- 2014-04-01
- 2014-03-21