A mini expression javascript template engine without any dependence. Compatible with client-side and server-side.
- 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.
A quick glance at the unit test maybe the most direct way to dive in.
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.
var hw = eoraptor.compile("Hello {{=name}}!");
hw({"name": "world"});
// "Hello 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"});
// "Hello 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 () {
// NOTE: The reality would be more complex than here
var ns = this["namespaceYouLike"] || {};
ns["hw"] = function (data){
var t__ = data, r__ = [];
r__.push("Hello ");
r__.push(t__.name);
r__.push("!");
return r__.join("");
};
// more functions
// ns["foo"] = function (data) {};
// ...
});
NOTE: The reality of namespace declaration
would be more complex than here, more details will be found in pre-compiling section.
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, thetemplate
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}}');
// method 1
fooTpl.render(data);
// method 2
fooTpl(data);
// method 3
eoraptor.foo(data);
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; // "function"
typeof eoraptor.sayAfternoon; // "function"
</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>
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"});
// "eoraptor.js"
{{=key}}
/ {{=["key"]}}
- key: required, the direct value of the
key
in context data.
Under the hood, the function returned by
eoraptor.compile()
is builded withoutwith
statement, so it will not throw errors likeunderscore
.
Demo: output the value of the key
in context data.
var tpl = eoraptor.compile("{{=name}}");
tpl.render({"name": "<h1>eoraptor.js</h1>"});
// "<h1>eoraptor.js</h1>"
Demo: if there is no such key
in context data.
var tpl = eoraptor.compile("{{this.name}}");
tpl.render({});
// "" empty string
{{-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>"});
// "<h1> eoraptor.js </h1>"
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);
// "like true"
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);
// "" empty string
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});
// "the number is two"
START with: {{^}}
END with: {{/}}
Demo:
var tpl = eoraptor.compile("the number is {{#this.number === 1}}"+
"one"+
"{{^}}"+
"unknown"+
"{{/}}");
tpl.render({});
// "the number is unknown"
{{#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 anumber
value(like 0, 1, 2, etc.) or astring
value determined by the iterative object, say,array
orobject
.
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);
// "<ul><li>0. eoraptor is simple</li><li>1. eoraptor is standalone</li></ul>"
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);
// "<ul><li>grammer:simple</li><li>dependency:standalone</li></ul>"
{{!comment}}
- comment, any word for the commit.
Demo:
var tpl = eoraptor.compile("{{!hello}}eoraptor.js");
tpl.render(); // "eoraptor.js"
{{/}}
You can see it everywhere above.
{{>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
intonaviList
andsliderList
, 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'}
]
}
});
// output:
// <p>navi:</p>
// <ul><li>foo</li><li>boo</li></ul>
// <p>slider:</p>
// <ul><li>1.jpg</li><li>2.jpg</li></ul>
The JavaScript Templates script is released under the MIT license.
- 2014-04-15
compile
method support zero parameter- update grunt task
- 2014-04-03
- add
extract
method
- add
- 2014-04-01
- add
eoraptor-jst
support
- add
- 2014-03-21
- initial version