Tags:
create new tag
view all tags

Template Toolkit

From the home of Template Toolkit 2:

The Template Toolkit is a fast, flexible and highly extensible template processing system. It is Free (in both senses: free beer and free speech), Open Source software and runs on virtually every modern operating system known to man. It is mature, reliable and well documented, and is used to generate content for countless web sites ranging from the very small to the very large.

It is written in the Perl programming language but you don't need to know any Perl to use it. In fact, it was specifically created to allow web designers and developers to concentrate on generating web pages without getting bogged down in programming matters. We call this a "Clear Separation of Concerns" and it makes the whole processes of building, updating and maintaining a web site or web application significantly easier.

Examples

Examples taken from http://template-toolkit.org/docs/manual/Intro.html

-----------------------------------------------------
[% FOREACH section = menu %]
   <a href="[% root %]/[% section %]/index.html">[% section %]</a>
[% END %]

<b>Client</a>: [% client.name %] (id: [% client.id %])
-----------------------------------------------------
[% IF shopcart.nitems %]
   Your shopping cart contains the following items:
   <ul>
   [% FOREACH item = shopcart.contents %]
     <li>[% item.name %] : [% item.qty %] @ [% item.price %]
   [% END %]
   </ul>
   [% checkout(shopcart.total) %]

[% ELSE %]
   No items currently in shopping cart.
[% END %]
-----------------------------------------------------
[% BLOCK tabrow %]
   <tr><td>[% name %]</td><td>[% email %]</td></tr>
[% END %]

<table>
[% PROCESS tabrow name="tom"   email="tom@here.org"    %]
[% PROCESS tabrow name="dick"  email="disk@there.org"  %]
[% PROCESS tabrow name="larry" email="larry@where.org" %]
</table>
-----------------------------------------------------
[%# this entire directive is ignored no
    matter how many lines it wraps onto
%]
-----------------------------------------------------
[% FOREACH item = [ 'foo' 'bar' 'baz' ] %]
   * Item: [% item %]
[% END %]
-----------------------------------------------------
[% BLOCK footer %]
   Copyright 2000 [% me %]
   [% INCLUDE company/logo %]
[% END %]
-----------------------------------------------------
[% SET foo = 10 %]
[% GET foo %]

[% foo = 10 %]
[% foo %]
-----------------------------------------------------
[% title or template.title or 'Default Title' %]
-----------------------------------------------------
[% mode == 'graphics' ? "Graphics Mode Enabled" : "Text Mode" %]
-----------------------------------------------------
[% headtext = PROCESS header title="Hello World" %]

[% people = PROCESS userinfo FOREACH user = userlist %]

[% PROCESS somefile | truncate(100) | html %]
-----------------------------------------------------
[% 15 / 6 %]            # 2.5
[% 15 div 6 %]          # 2
[% 15 mod 6 %]          # 3
-----------------------------------------------------
[% CALL dbi.disconnect %]
[% CALL inc_page_counter(page_count) %]
-----------------------------------------------------
[% foo  = 'Foo'  %]               # literal value 'Foo'
[% bar  =  foo   %]               # value of variable 'foo'
[% cost = '$100' %]               # literal value '$100'
[% item = "$bar: ${cost}.00" %]   # value "Foo: $100.00"
[% copyright = '(C) Copyright' _ year _ ' ' _ author %]
[% copyright = "(C) Copyright $year $author" %]
-----------------------------------------------------
[% DEFAULT
    name = 'John Doe'
    id   = 'jdoe'
%]
-----------------------------------------------------
[% INSERT misc/legalese.txt            %]
[% INSERT 'dos98/Program Files/stupid' %]
-----------------------------------------------------
[% SWITCH myvar %]
[%   CASE 'value1' %]
       ...
[%   CASE ['value2', 'value3'] %]   # multiple values
       ...
[%   CASE myhash.keys %]            # ditto
       ...
[%   CASE %]                        # default
       ...
[% END %]
-----------------------------------------------------
[% userlist = [
    { id => 'tom',   name => 'Thomas'  },
    { id => 'dick',  name => 'Richard'  },
    { id => 'larry', name => 'Lawrence' },
   ]
%]

[% FOREACH user IN userlist %]
   [% user.id %] [% user.name %]
[% END %]
-----------------------------------------------------
[% users = {
     tom   => 'Thomas',
     dick  => 'Richard',
     larry => 'Lawrence',
   }
%]

[% FOREACH u IN users %]
   * [% u.key %] : [% u.value %]
[% END %]
-----------------------------------------------------
[% USE giter = iterator(grouplist) %]

[% FOREACH group IN giter %]
   [% FOREACH user IN group.userlist %]
         user #[% loop.count %] in
         group [% giter.count %] is
         named [% user.name %]
   [% END %]
[% END %]
-----------------------------------------------------

-- Contributors: LesOrchard, PeterThoeny

Discussion

I've been using the TemplateToolkit for a few years now, and have been wholly converted to it. IMHO, it is heading toward being The Ultimate Templating System for perl. It allows for a very clean separation between logic and presentation via hash namespaces used in populating the templates. And although extremely flexible out of the box, the system is completely extensible via plugins which add new capabilities into the template environment, provide tags to define filter blocks in which content is processed through code.

There is even a very flexible architecture in how the system finds templates in the first place. The plain vanilia manner, or course, is to read them straight from file storage in a directory. However, one can supply new "Template provider" classes to allow the system to find, compile, and cache templates from database tables, from in-memory hashes, basically from any source you can wrap an object around.

And one more thing: The TemplateToolkit is not restricted to HTML, and can be used to generate any text document type. In fact, newer plugins look like generating templated images (ie. via GD image generation libraries) from the template namespace data.

-- LesOrchard - 01 Jun 2001

This has been throw around a bit. I've been looking at it myself, although last time I fiddled with TemplateToolkit was 12 months ago. I'm not sure what the state of the are is now.

The main thing to consider I see, is defining a clear path for the TWiki syntax rendering to be understood by TemplateToolkit. If it can be done without forcing a change in the syntax defined TextFormattingRules that would be great.

-- NicholasLee - 04 Jun 2001

Basically, the TextFormattingRules could stay the same. TemplateToolkit has a facility for defining filter tags. So, wherever in a TWiki template that content following the TextFormattingRules appears might look something like:

[% FILTER TWikiFilter %]
  $content
[% END %]

...where $content contains the text of the content, of course. The implementation of a filter plugin is basically some plugin boilerplate surrounding a single sub into which the text inside the [% FILTER %] construct is passed, and the filtered text returned. So, all the regexes implementing the TextFormattingRules could be collected there.

The only things one might want to have different are things like how TWikiVariables are included and the other miscellaneous little constructs and function calls in the %...% syntax. They could just be implemented along site the other formatting rules in the filter, but here one might want to take advantage of TemplateToolkit features here.

For instance, TemplateToolkit does a very good job of managing access to variables and objects in the template namespace. Plain variables can just be thrown into the namespace hash. So instead of % SERVERTIME%, it would be $SERVERTIME. Or, one could organize all the variables under another namespace key, so maybe $TWiki.SERVERTIME.

As for the programmatic elements, such as % INCLUDE{...}%, TemplateToolkit also allows access to plugin object methods. So, maybe create a TWiki utility object with a method include. % INCLUDE{..}% could turn into $TWiki.include('filename'). And, in this way, new TWiki functions could be added simply as methods to the hypothetical TWiki utility plugin object. No mussing with regexes to parse all the arguments, etc...

And on top of all of this, you get basic conditional and looping constructs, and only as much system level access as your plugins allow. So, no opening files unless you supply a file access plugin, etc...

-- LesOrchard - 05 Jun 2001

How about turning off access to certain features of TT within the main content body. ie. Otherwise we might create a security hole.

-- NicholasLee - 06 Jun 2001

The toolkit is very powerful and can also be extended with plugins, i.e. the tutorial mentions a DB plugin where you can specify a SQL query and loop through the rows to display the result.

This is all nice but it probably is not a good fit for TWiki:

  • The TemplateToolkit is BIG, only the lib directory is over 1 MB. That would mean an increased CPU load and memory load for each topic view.
  • The TWiki core should stay lean and not depend on too many external modules. (Plugins are excluded)
  • There is an overlap of functionality of the TemplateToolkit and TWiki, i.e. the plugin.
  • The syntax is (not surprisingly) not a good fit.

As mentioned in CommonHeaderFooterTemplate it makes sense to define common patterns just once, i.e. the header and the footer so that it is easy to change them. Since the TemplateToolkit is not suitable we should roll our own TWikiTemplatingSystem.

-- PeterThoeny - 21 Jul 2001

Further discussion refactored to BetterTemplateSystem

-- CrawfordCurrie - 2004-10-14

Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formatgz TTFormsPlugin.tar.gz r1 manage 5.6 K 2003-01-08 - 13:03 UnknownUser Template Toolkit - Sample plugin
Edit | Attach | Watch | Print version | History: r37 < r36 < r35 < r34 < r33 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r37 - 2010-06-19 - PeterThoeny
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.