Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

TWIG-like Templates in Objective-C

This is now an open source project called MulleScion on Mulle kybernetiK. This is an older text, introducing it.


When I installed and customized gitlist on Mulle, I really liked the PHP template engine they used called TWIG. I wanted something like this for myself but preferably in C or in Objective-C. But I didn't find anything, that was very TWIG like. Inspired by this anecdote of Dadhacker, I figured if that guy can write an assembler in four hours maybe I can write a template engine in four.... oh well days :)

And that's what I did. The code fairly quickly was able to use a template like this:

<html>
<!-- rendered by on -->
<body>
<table>
<tr><th>TimeZone</th></tr>
<tr bgcolor=""><td></td></tr>
</table>
Sorry, no timezone info available.
</body>
</html>

to render HTML output like that:

<html>
<!-- rendered by mulle-scion on 2013-02-27 16:27:05 +0000
-->
<body>
<table>
<tr><th>TimeZone</th></tr>
<tr
bgcolor="#DDDDDD"><td>Africa/Abidjan</td></tr>
<tr
bgcolor="#FFFFFF"><td>Africa/Accra</td></tr>
<tr
bgcolor="#DDDDDD"><td>Africa/Addis_Ababa</td></tr>
<tr
bgcolor="#FFFFFF"><td>Africa/Algiers</td></tr>
<tr
bgcolor="#DDDDDD"><td>Africa/Asmara</td></tr>
<tr
bgcolor="#FFFFFF"><td>Africa/Bamako</td></tr>
</body>
</html>

Now it can do pretty much all that TWIG can, like extending and overriding blocks.

It's a fairly capable Objective-C interpreter with auto-boxing support. I can even write [string substringToIndex:NSMakeRange( 0, [string length] - 1]).length] into my template and it should work.

 Pretty nifty :)

Here's the README, as of version 1849:

MulleScion is a modern template engine for Objective C

(written in an oldfashioned way)


It's heavily (very heavily) inspired by

TWIG "The flexible, fast, and secure template engine for PHP"

MulleScion is fairly flexible, reasonably fast and can be made as secure as you wish.

  • Reasonably Fast : MulleScion can compile templates into a compressed archive format. Loading such an archive ought to be lots faster than parsing (but because the parse is so fast, maybe isn't). A compiled template is read-only, you can use it many times to render different output from different input.

  • Secure : MulleScion has hooks so your application can ensure that untrusted template code doesn't have access to all of the applications data.

  • Flexible : There is the possibility of extending KVC and writing your own "builtin" fuctions. A template can (if allowed) execute arbitrary ObjC code. MulleScion has a powerful define like preprocessing capability and macros to expand your template vocabulary.

Here is a simple example, where ObjC code is embedded in a template:

<pre><code>&lt;html&gt;
&lt;!-- rendered by {{ [[NSProcessInfo processInfo] processName] }} on
    {{ [NSDate date] }} --&gt;
&lt;body&gt;
{% for item in [NSTimeZone knownTimeZoneNames] %}
    {% if item#.isFirst %}
&lt;table&gt;
   &lt;tr&gt;&lt;th&gt;TimeZone&lt;/th&gt;&lt;/tr&gt;
    {% endif %}
   &lt;tr&gt;&lt;td&gt;{{ item }}&lt;/td&gt;&lt;/tr&gt;
    {% if item#.isLast %}
&lt;/table&gt;
    {% endif %}
{% else %}
Sorry, no timezone info available.
{% endfor %}
&lt;/body&gt;
&lt;/html&gt;</code></pre>

Using the MulleScion.framework the creation of a string from your object using a template file is as easy as:

NSString  *output;

output = [MulleScionTemplate descriptionWithTemplateFile:@"test.scion"
                                              dataSource:self];

This is the general architecture of MulleScion

MulleScion is happily used in a commercial project and has gone through enough iterations to pronounce it "ready for production".

TOOLS

There is an interactive editor available for OS X called MulleScionist, which allows you to edit a HTML scion template and preview the results at the same time.

DOCUMENTATION

Virtually all the documentation is contained in example .scion templates in the dox folder. For each command or feature there should be a separate template file that documents it. mulle-scion, the command line utility, contains a small quickly hacked together webserver that can present the documentation using MulleScion itself.

In Xcode just run Show Documentation in Webserver and it should setup the webserver and open your browser to the right address.

MulleScion is very similar to TWIG, so you can glean much of relevance from twig.sensiolabs.org. If you see a feature in TWIG but don't see it in the tests file, it's likely not there (but it's probably easily achieved some other way (using a define or a macro or an ObjC category on NSString).

LIMITATIONS

Because you can execute arbitrary ObjC methods, and have access to Key Value Coding, MulleScion can pretty much do anything. MulleScion uses NSInvocation for method calls. That means there will be problems with variable arguments methods. Be wary of anything using structs and C-Arrays and C-strings, although MulleScion tries to be as helpful as possible.

MulleScion does not do arithmetic or bitwise logic, quite on purpose.

MulleScion && and || have no operator precedence, use parentheses.

MulleScion doesn't prevent you from trying stupid things.

The documentation is not very good, actually it is just more or less a collection of test cases with comments...

iOS SUPPORT

There is iOS Support :)

SITES

The main development site is Mulle kybernetiK.

/software/git/MulleScion/

releases are pushed to github

https://github.com/mulle-nat/MulleScion/

TODO

It might be nice to have delayed evaluation for render results. More tests.

AUTHOR

Coded by Nat! 2013 Mulle kybernetiK

Mongoose Webserver by Sergey Lyubka

Hoedown Library by Natacha Porté Vicent Martí Xavier Mendez, Devin Torres and the Hoedown authors