++ed by:

2 PAUSE users
4 non-PAUSE users.

Вячеслав Тихановский

Text::Caml is a Mustache-like (http://mustache.github.com/) template engine. That means it tends to have no logic in template files.


    my $view = Text::Caml->new;

    my $output = $view->render_file('template', {title => 'Hello', body => 'there!'});

    # template

    $output = $view->render('{{hello}}', {hello => 'hi'});



Context is the data passed to the template. Context can change during template rendering and be specific in various cases.


Variables are inserted using {{foo}} syntax. If a variable is not defined or empty it is simply ignored.

    Hello {{user}}!

By default every variable is escaped when parsed. This can be omitted using & flag.

    # user is '1 > 2'
    Hello {{user}}! => Hello 1 &gt; 2!

    Hello {{&user}}! => Hello 1 > 2!

Using a . syntax it is possible to access deep hash structures.

    # user => {name => 'Larry'}



Comments are ignored. They can be multiline too.

  foo{{! Comment}}bar



Sections are like iterators that iterate over your data. Depending on a variable type different iterators are created.

  • Boolean, have_comments is defined, not zero and not empty.

        # have_comments => 1
        We have comments!
        We have comments!
  • Array, list is a non-empty array reference. Special variable {{.}} is created to point to the current element.

        # list => [1, 2, 3]
  • Hash, hash is a non-empty hash reference. Context is swithed to to the elements.

        # hash => {one => 1, two => 2, three => 3}
  • Lambda, lambda is an anonymous subroutine, that's called with three arguments: current object instance, template and the context. This can be used for subrendering, helpers etc.

        wrapped => sub {
            my $self = shift;
            my $text = shift;
            return '<b>' . $self->render($text, @_) . '</b>';
        {{name}} is awesome.
        <b>Willy is awesome.</b>

Inverted sections

Inverted sections are run in those situations when normal sections don't. When boolean value is false, array is empty etc.

    # repo => []
      No repos :(

    No repos :(


Partials are like inludes in other templates engines. They are run with the current context and can be recursive.