Skip to content
Andrew Luca edited this page Sep 22, 2021 · 26 revisions

twig.js

Build Status

About

Twig.js is a pure JavaScript implementation of the Twig PHP templating language (https://twig.symfony.com/)

The goal is to provide a library that is compatible with both browsers and server side containers such as node.js.

Twig.js is currently a work in progress and supports a limited subset of the Twig templating language (with more coming).

NEWS

  • 6/10/2016 - Twig is now available as a template engine in Keystone.js

Download

You can get Twig.js by any of the following methods:

  1. Clone the repository

    git clone git://github.com/justjohn/twig.js.git

  2. Download an archive of the latest as a zip or tgz

The files twig.js and twig.min.js may not be up-to-date (they will be rebuilt when releasing a new version). Run make (or make -B to force building) to create these files.

Implementation Details

See the implementation details wiki page for a list of supported filters/functions/tags/tests.

Node Usage

Twig.js is available as a Node package which you can install from npm

npm install twig

Usage without Express

If you don't want to use Express, you can render a template with the following method:

import Twig from 'twig';
Twig.renderFile('./path/to/someFile.twig', {foo:'bar'}, (err, html) => {
  html; // compiled string
});

Twig.js is compatible with Express 2 and 3 and can be setup with the following code:

app.js

Express 3

var express = require('express'),
    app = express();

app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'twig');

    // This section is optional and can be used to configure twig.
    app.set('twig options', { 
        strict_variables: false
    });
});

app.get('/', function(req, res){
    res.render('index', {
        message : "Hello World"
    });
});

app.listen(9999);

views/index.twig

Message of the moment: <b>{{ message }}</b>

Using a custom file extension

You can use a custom file extension by registering twig as the view engine for the extension you want. For example, to use the html extension, you would use:

twig = require('twig');

// ... in app.configure
app.set('view engine', 'html');
app.engine('html', twig.__express);

See the Express 2 page for compatibility with Express 2.

Browser Usage

From the browser, Twig.js can be used with inline templates or templates loaded from AJAX.

Inline Templates

var template = Twig.twig({
    id: "list", // id is optional, but useful for referencing the template later
    data: "{% for value in list %}{{ value }}, {% endfor %}"
});

var output = template.render({
    list: ["one", "two", "three"]
});

// output = "one, two, three, "

If an id is provided when you create a template, you can reference the template anywhere else in your application by using the ref parameter:

// Elsewhere in your application
var output = Twig.twig({ ref: "list" }).render({
    list: ["a", "b", "c"]
});

// output = "a, b, c, "

AJAX Templates

Templates can also be loaded via ajax by setting the href parameter in the twig() options.

templates/posts.twig

{% for post in posts %}
    <article>
        <header>
            <h1>{{ post.title }}</h1>
        </header>
        <p>{{ post.body }}</p>
    </article>
{% endfor %}

app.js

var template = twig({
    id: "posts",
    href: "templates/posts.twig",
    // for this example we'll block until the template is loaded
    async: false

    // The default is to load asynchronously, and call the load function 
    //   when the template is loaded.

    // load: function(template) { }
});

Once you've loaded templates, you can access them via their id and render them when you have data.

posts = { ... }; // data from somewhere like an AJAX callback

// render the template
var postsHTML = twig({ ref: "posts" }).render(posts);

// Display the rendered template
document.getElementById("posts").innerHTML = postsHTML;

Namespaces

var template = Twig.twig({
    data: 'your-template',
    namespaces: { 'my-project': 'path/to/views/folder/' }
}).render();

When referencing another template, instead of using the relative path you can use the namespaces that were previously defined.

Ex:

{# your-template.twig #}
{% extends "my-project::template.twig" %}

The "my-project::" will now point to "path/to/views/folder/". It works with the @ sign too:

{% include '@my-project/template.twig' %}