Combyne
A template engine that works the way you expect.
Stable: 0.3.1

No dependencies. Can be loaded as a browser global, AMD module, Node module,
and Browserify module. Can be installed via NPM or Bower.
Getting started.
Combyne can run under a variety of JavaScript engines and loaders:
Node.
npm install combyne
Require in your source:
var combyne = require("combyne");
AMD.
require({
paths: {
combyne: "path/to/combyne"
}
});
define(["combyne"], function(combyne) {});
Browser global.
Include the latest stable
in your markup:
<script src="combyne.js"></script>
Basic usage.
var tmpl = combyne("hello {{msg}}!");
tmpl.render({ msg: "world" });
Features.
Combyne works by parsing your template into a stack and rendering data.
Combyne works by parsing your template into an AST. This provides mechanisms
for intelligent compilation and optimization. The template is converted to
JavaScript and invoked upon calling render.
Comments are useful for ignoring anything between the open and close. They can
be nested.
var tmpl = combyne("test {%-- not parsed --%}");
tmpl.render();
Custom delimiters.
If you are not happy with the default Mustache-like syntax, you can trivially
change the delimiters to suit your needs. The delimiters may be changed at a
local or global level.
combyne.options.delimiters = {
START_PROP: "[[",
END_PROP: "]]"
};
var tmpl = combyne("[[msg]]", { msg: "hello world" });
tmpl.render();
Replacing template variables.
var template = "{{lol}}";
var context = { lol: "test" };
var tmpl = combyne(template);
var output = tmpl.render(context);
Using filters on variables.
var template = "{{lol|reverse}}";
var context = { lol: "test" };
var tmpl = combyne(template);
tmpl.registerFilter("reverse", function(val) {
return val.split("").reverse().join("");
});
var output = tmpl.render(context);
Passing arguments to filters.
You may find that the property value is not enough information for the filter
function, in which case you can send additional arguments.
var tmpl = combyne("{{ code|highlight 'javascript' }}");
tmpl.registerFilter("highlight", function(code, language) {
return highlight(code, language);
});
Chaining filters on variables.
var template = "{{lol|reverse|toUpper}}";
var context = { lol: "test" };
var tmpl = combyne(template);
tmpl.registerFilter("reverse", function(val) {
return val.split("").reverse().join("");
});
tmpl.registerFilter("toUpper", function(val) {
return val.toUpperCase();
});
var output = tmpl.render(context);
Conditionals.
Instead of being logic-less, combyne
doesn't make any assumptions and
allows you to do things like if/elsif/else
with simple conditionals,
such as if something == somethingElse
or if not something
. All data
types will be coerced to Strings except for Numbers.
var template = "{%if not test%}why not?{%endif%}";
var context = { test: false };
var tmpl = combyne(template);
var output = tmpl.render(context);
or a more complicated example...
var template = "{%if test == 'hello'%}goodbye!{%else%}hello!{%endif%}";
var context = { test: "hello" };
var tmpl = combyne(template);
var output = tmpl.render(context);
Iterating arrays.
Will not work on array-like objects, such as arguments or NodeList, coerce with
Array.prototype.slice.call(obj);
var template = "{%each test%}{{.}} {%endeach%}";
var context = { test: [1,2,3,4] };
var tmpl = combyne(template);
var output = tmpl.render(context);
Change the iterated identifer within loops.
var template = "{%each arr as _%}{{_}}{%endeach%}";
var context = { arr: [1,2,3] };
var tmpl = combyne(template);
var output = tmpl.render(context);
Iterating objects.
var template = "{%each test as key val%}the {{key}} is {{val}}{%endeach%}";
var context = {
test: {
hello: "lol"
}
};
var tmpl = combyne(template);
var output = tmpl.render(context);
Partials.
var template = "{{test}} {%partial test%}";
var context = { test: "hello" };
var tmpl = combyne(template);
tmpl.registerPartial("test", combyne("{{name}}", {
name: "you"
}));
var output = tmpl.render(context);
Unit tests.
There are many ways to run the unit tests as this library can operate in
various environments.
Browser
Open test/index.html in your web browser.
Node
Run the tests inside the Node runtime and within PhantomJS:
grunt test
Continuous testing
To keep the PhantomJS tests running continuously, run:
grunt karma:daemon
The tests will automatically run whenever files change.
Code coverage
If you run the tests through Karma, a test/coverage directory will be created
containing folders that correspond with the environment where the tests were
run.
If you are running the defaults you should see something that looks like:
.
└── coverage
├── Chrome 33.0.1750 (Linux)
└── PhantomJS 1.9.7 (Linux)
Inside PhantomJS contains the HTML output that can be opened in a browser to
inspect the source coverage from running the tests.