App::ZofCMS::Plugin::Tagged - ZofCMS plugin to fill templates with data from query, template variables and configuration using <TAGS>


Your ZofCMS template:

        cookie_foo  => '<TAG:TNo cookies:{d}{cookies}{foo}>',
        query_foo   => '[<TAG:Q:{foo}>]',
        set_cookies => [ ['foo', 'bar' ]],
        plugins     => [ { Cookies => 10 }, { Tagged => 20 } ],
        conf => {
            base => 'test.tmpl',

In your 'test.tmpl' base HTML::Template template:

    Cookie 'foo' is set to: <tmpl_var name="cookie_foo"><br>
    Query 'foo' is set to: <tmpl_var name="query_foo">

In ZofCMS template the Cookies plugin is set to run before Tagged plugin, thus on first page access cookies will not be set, and we will access the page without setting the 'foo' query parameter. What do we see:

    Cookie 'foo' is set to: No cookies
    Query 'foo' is set to: []

No, if we run the page the second time it (now cookies are set with App::ZofCMS::Plugin::Cookies plugin) will look like this:

    Cookie 'foo' is set to: bar
    Query 'foo' is set to: []

If we pass query parameter 'foo' to the page, setting it to 'beer' our page will look like this:

    Cookie 'foo' is set to: bar
    Query 'foo' is set to: [beer]

That's the power of Tagged plugin... now I'll explain what those weird looking tags mean.


The module provides means to the user to use special "tags" in scalar values inside ZofCMS template. This provides the ability to display data generated by templates (i.e. stored in {d} first level key), access query or configuration hashref. Possibilities are endless.

This documentation assumes you have read documentation for App::ZofCMS including App::ZofCMS::Config and App::ZofCMS::Template


First of all, when using App::ZofCMS::Plugin::Tagged with other plugins make sure to set the correct priority. In our example above, we used App::ZofCMS::Plugin::Cookies which reads currently set cookies into {d} special key in ZofCMS template. That's why we set priority of 10 to Cookies plugin and priority of 20 to Tagged plugin - to insure Tagged runs after {d}{cookies} have been filled in.

Note: currently there is no support to run Tagged plugin twice, I'm not sure that will ever be needed, but if you do come across such situation, you can easily cheat. Just copy in your $core/App/ZofCMS/Plugin/ to (and ajust the name accordingly in the package line inside the file). Now you have two Tagged plugins, and you can do stuff like plugins => [ {Tagged => 10}, { SomePlugin => 20 }, { Tagged2 => 30 } ]


    foo => '<TAG:Q:{foo}>',
    bar => 'beeer <TAG:Qdefault:{bar}>  baz',
    baz => 'foo <TAG:T:{d}{baz}[1]{beer}[2]> bar',
    nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",
    random => '<TAG::RAND I 100>',

NOTE: everything in the tag is CASE-SENSITIVE

First of all, the tag starts with '<TAG:' and ends with with a closing angle bracket ('>'). The first character that follows '<TAG:' is a cell. It can be either 'Q', 'T' or 'C', which stand for Query, Template and Configuration file. Each of those three cells is a hashref: a hashref of query parameters, your ZofCMS template hashref and your main configuration file hashref.

What follows the cell letter until the colon (':') is the default value, it will be used if whatever your tag references is undefined. Of course, you don't have to define the default value; if you don't - the tag value will be an empty string (not undef). Note: currently you can't use the actual colon (':') in your default variable. Currently it will stay that way, but there are plans to add custom delimiters in the future.

After the colon (':') which signifies the end of the cell and possible default value follows a sequence which would access the value which you are after. This sequence is exactly how you would write it in perl. Let's look at some examples. First, let's define $template, $query and $config variables as T, Q and C "cells", these variables hold respective hashrefs (same as "cells"):

    <TAG:Q:{foo}>              same as   $query->{foo}
    <TAG:T:{d}{foo}>           same as   $template->{d}{foo}
    <TAG:C:{ fo o }{ b a r }>  same as   $config->{"fo o"}{"b a r"}
    <TAG:Qnone:{foo}>          same as   $query->{foo} // 'none'
    <TAG:Txxx:{t}{bar}>        same as   $template->{t}{bar} // 'xxx'

    # arrayrefs are supported as well

    <TAG:T:{d}{foo}[0]>        same as   $template->{d}{foo}[0]
    <TAG>C:{plugins}[1]>       same as   $config->{plugins}[1]


    rand1 => '<TAG:RAND>',
    rand2 => '<TAG:RAND 100>',
    rand3 => '<TAG:RAND I 200>',
    rand4 => '<TAG:RAND100>',
    rand5 => '<TAG:RANDI100>',

The RAND tag will be replaced by a pseudo-random number (obtained from perl's rand() function). In it's plainest form, <TAG:RAND>, it will be replaced by exactly what comes out from rand(), in other words, same as calling rand(1). If a letter 'I' follows word 'RAND' in the tag, then int() will be called on the result of rand(). When a number follows word RAND, that number will be used in the call to rand(). In other words, tag <TAG:RAND 100> will be replaced by a number which is obtained by the call to rand(100). Note: the number must be after the letter 'I' if you are using it. You can have spaces between the letter 'I' or the number and the word RAND. In other words, these tags are equal: <TAG:RANDI100> and <TAG:RAND I 100>.


    nop => "<TAG:NOOP><TAG:T:I'm NOT a tag!!!>",

The NOOP tag (read no operation) is a special tag which tells Tagged plugin to stop processing this string as soon as it sees this tag. Tagged will remove the noop tag from the string. The above example would end up looking as nop => "<TAG:T:I'm NOT a tag!!!>",

Note: any tags before the noop tag WILL be parsed.


        tagged_options => { no_parse => 1 },

Behaviour options can be set for App::ZofCMS::Plugin::Tagged via tagged_options first level ZofCMS template key. This key takes a hashref as a value. The only currently supported key in that hashref is no_parse which can be either a true or a false value. If it's set to a true value, Tagged will not parse this template.


This plugin requires Data::Transformer module which is not in Perl's core. If your webserver does not allow instalation of modules from CPAN, run the helper script to copy this module into your $core_dir/CPAN/ directory

    zofcms_helper --nocore --core your_sites_core --cpan Data::Transformer


If your tag references some element of ZofCMS template which itself contains a tag the behaviour is undefined.


App::ZofCMS, App::ZofCMS::Config, App::ZofCMS::Template


Fork this module on GitHub:


To report bugs or request features, please use

If you can't access GitHub, you can email your request to bug-App-ZofCMS at


Zoffix Znet <zoffix at> (,


You can use and distribute this module under the same terms as Perl itself. See the LICENSE file included in this distribution for complete details.