Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include Template::Toolkit- Macros?

This question is about the usage of macros from Template::Toolkit (Perl)

I`m failing to write macros and putting them into a separate file to use them within several other template files.

My macros are located in a separate template file named macros.tt:

----- file macros.tt ------
[% MACRO decorateStatus(status) BLOCK -%]
    [% ico = 'status_unknown' -%]
    [% IF status == "New" -%][% ico = 'status_waiting' -%]
    [% ELSIF status == "Working" -%][% ico = 'status_work' -%]
    [% ELSIF status == "Deleted" -%][% ico = 'status_deleted' -%]
    [% END -%]
    [% status %] <img src="[% c.uri_for('/images/ico/' _ ico _ '.png') %]" text="[% status %]">
[% END-%]

Now I’m trying to use this macro within another template – but this fails as the macro is not expanded:

----- file demo.tt -------
[% INCLUDE macros.tt %]
….
[% status = ‘New’ %]
<td>[% decorateStatus(status) %]</td>
….

Putting the macro directly in the file where I want to use it, everything works as expected.

What’s the “correct” way to include macros from a different file?

like image 540
hoppfrosch Avatar asked Jan 05 '23 17:01

hoppfrosch


2 Answers

Using INCLUDE, all variable definitions (and a macro is really just a fancy variable) are localised to the included file. Which means the macros definitions aren't visible outside of the included file.

To make the macros visible in the calling file, you need PROCESS instead of INCLUDE. As the documentation says:

The PROCESS directive is similar to INCLUDE but does not perform any localisation of variables before processing the template. Any changes made to variables within the included template will be visible in the including template.

like image 155
Dave Cross Avatar answered Jan 13 '23 14:01

Dave Cross


If you are using more than 1 template file with macros shared among them, try this:

Easier and cleaner than including [% PROCESS 'macros.tt' %] in every template is to make TT process your macros file before every call with PRE_PROCESS.

use Template;

my $tt = Template->new({
    INCLUDE_PATH => '/usr/local/templates',
    PRE_PROCESS  => 'macros.tt',
})
like image 39
Daniel Böhmer Avatar answered Jan 13 '23 15:01

Daniel Böhmer