Fork me on GitHub

Jerrymarker is an open-source template engine in javascript. Based on the parser generated by jison, it's easy to custome the lexical and grammer rules to build a powerful parser in javascript. Jerrymarker maintains a simple syntax tree for your template and render it by traversing. It also provides the necessary to build your templates. As a light-weighted template engine, jerrymarker is easy to learn since the rules in jerrymarker template is just like what is in freemarker which is a template engine commonly used in Java.

Jerrymarker's target is "jerrymarker = javascript + freemarker-- ++".

Getting Start

Jerrymarker templates look like HTML, with embeded interpolations and directives.

<div class="entry" >
    <#if job == "programmer" >
        Hello, ${name}
    </#if>
</div>

the <#if> is a directive while ${name} is an interpolation expression.

For web page, you can put the template in a script tag.

<script id="book" type="text/x-jerrymarker-template" >
    <h2>${title}</h2>
    <h4>by ${author.name}(${author.d1} ~ ${author.d2})</h4>
</script>

In the javascript part, you can use the template like this.

var nd = document.getElementById('book');
var source = nd.innerHTML;
var template = jerrymarker.compile(source);

All you need to do is to render the template with a context object.

var book = {
    title: "Pride and Prejudice",
    author: {
        name: "Jane Austen",
        d1: 1775,
        d2: 1817
    }
};
var html = template(book);

And result in

<h2> Pride and Prejudice </h2>
<h4> by Jane Austen(1775 ~ 1817) </h4>

Values & Types

Jerrymarker now only support 2 literal value types as Number and String.

<#assign a = 100 >
<#assign b = 0.01 >
<#assign c = 'string' >
<#assign d = "string" >

You can declare a variable via assign directive, the lexical rule is just like javascript(letters or letters plus digits). So you can use v = xx, v1 = xx, but not 1v = xx. Boolean, Array and Hash types are in schedule now.

Interpolations

The format of interpolations is ${expression}, where expression can be all kind of expression (e.g. ${100 + x}).

Expressions

When you supply value for interpolations: The usage of interpolations is ${expression} where expression gives the value you want to insert into the output as text.

${x*2+(3+4)*5}

When you supply a value for the directive parameter: You have already seen the if directive in the Getting Started section. The syntax of this directive is: <#if expression>...</#if >.

<#if ((x < 100) && !(x <= 50)) >
    x is greater than 50 and less than 100
</#if>

Jerrymarker now supports +. -. *, /, %, !, (), '>', '<', '!=', '>=', '=>', '&&', '||'.

There is another set of special operators including ?? !, and other operators starting with ?. For example, ?html will output the escaped value, jerrymarker hopes to implement some build-in functions which is often used in freemarker template.

Use the build-in ?html to encode the html special chars.

<#assign x = "<span>Hi</span>" >
${x}

<#assign y = "<span>Hi</span>"?html >
${y}

The result is

<span>Hi</span>


&lt;span&gt;Hi&lt;/span&gt;

Use the build-in ?? with if directive

<#if x?? && x < 100 >
    x exists and x < 100
</#if>

Use x!y in interploation

${x!100}  //if x exists output x or output 100

Warning! It may be wrong if you use '>' operator without '()' since '>' will be parsed as the close '>' for directives. If you have used freemarker, you will find the wrong case in freemarker too.

//wrong
<#if x > 100 >
    ${x}
</#if>

//corrected
<#if (x > 100) >
    ${x}
</#if>

Directive List

Example 1: You can use list to count between two numbers

<#assign x = 1 >
<#list x..10 as i>
    ${i}
</#list>

The output will be

1
2
3

Example 2: You can use the list directive to process a section of template for each variable contained within a Array.

<div>
    <ul>
        <#list animals as animal>
            <#if animal.cate == "insect" >
                <li>${animal.name}</li>
            </#if>
        </#list>
    </ul>
</div>
var context = {
    animals: [
        {
            cate: 'insect',
            name: 'fly'
        },
        {
            cate: 'insect',
            name: 'butterfly'
        },
        {
            cate: 'mammal',
            name: 'panda'
        }
    ]
}

The output will be

<ul>
<li>fly</li>
<li>butterfly</li>
</ul>

Directive Assign

Now only support <#assign name=value>, name: name of the variable. It is not expression, value: the value to store. Expression.

<#assign counter = 0>
<#list 1..10 as i>
    <#if i % 2 == 0 >
        <#assign counter = counter + 1 >
    </#if>
</#list>
the event number is ${counter}

And result in

the event number is 5