Table of Contents

Creation of a tpl tag for a plugin or a theme

Introduction

For a plugin or a theme, existing tpl tags are not always enough, and we sometimes need to create our own. For this purpose, we have to write functions in the _public.php file of the plugin/theme.

There are two kinds of tpl tags : value tags and instruction blocks.

Important:

A tpl function must return a PHP code, which will be interpreted every time the page is displayed. If the function returns HTML code, the content will be stored in the cache and will change only when the cache is cleared.

Values

{{tpl:tag}}

This kind of tag returns a string.

Declaration statement

The declaration is made with the addValue() function :

$core->tpl->addValue('CoreVersion',array('tplMyMoreTpl','CoreVersion'));

The first parameter is the tpl tag name. Here, its name is CoreVersion.

The second parameter indicates a class, and a function belonging to this class. Here, the CoreVersion function of the tplMyMoreTpl class will be called.

Class and function

class tplMyMoreTpl
{
    public static function CoreVersion($attr)
    {
        $f = $GLOBALS['core']->tpl->getFilters($attr);
 
        return
        '<?php echo '.sprintf($f,'$GLOBALS["core"]->getVersion()').'; ?>';
    }
}

This function displays Dotclear's version number. The first line of the function allows us to use template tags attributes.

They are not always necessary so the function could be simplified :

class tplMyMoreTpl
{
    public static function CoreVersion()
    {
        return
        '<?php echo $GLOBALS["core"]->getVersion(); ?>';
    }
}

Complete code

$core->tpl->addValue('CoreVersion',array('tplMyMoreTpl','CoreVersion'));
 
class tplMyMoreTpl
{
    public static function CoreVersion($attr)
    {
        $f = $GLOBALS['core']->tpl->getFilters($attr);
 
        return
        '<?php echo '.sprintf($f,'$GLOBALS["core"]->getVersion()').'; ?>';
    }
}

Warning:

The declaration statement is made outside of the class.

Instructions blocks

<tpl:tag>
...
</tpl:tag>

This is a block tag. The difference between value tags and block tags lies in their syntax (<tpl:tag> instead of {{tpl:tag}) but also their behaviors. Block tags return a block of PHP code that allows loops, conditional loops, etc.

Declaration statement

In this case, the function addBlock() is used instead of addValue()

$core->tpl->addBlock('EntryIfPosition',array('tplMyMoreTpl','EntryIfPosition'));

The first parameter is the tpl tag name. Here, its name is EntryIfPosition.

The second parameter must be a class and a function belonging to this class. Here, the function EntryIfPosition of the tplMyMoreTpl class will be called.

Class and function

class tplMyMoreTpl
{
    public static function EntryIfPosition($attr,$content)
    {
        $is = isset($attr['is']) ? trim($attr['is']) : '';
        $expr = self::testInExpr($is,'$idx');
        return
        '<?php $idx = $_ctx->posts->index()+1; if ('.$expr.'): ?>'.
        $content.
        '<?php endif; unset($idx); ?>';
    }
}

This function checks a post's position compared to the "is" argument that contains accepted position, separed by comas. The function takes two parameters : * $attr which is an array. This way, the parameter "is" of this tag <tpl:EntryIfPosition is="1"> can be retrieved in the function using $attr['is'].

Warning:

This last parameter is very important. Forgetting it would mean the loop won't care for the content placed in between the tags.

Complete code

$core->tpl->addBlock('EntryIfPosition',array('tplMoreTpl','EntryIfPosition'));
 
class tplMoreTpl
{
    public static function EntryIfPosition($attr,$content)
    {
        $is = isset($attr['is']) ? trim($attr['is']) : '';
        $expr = self::testInExpr($is,'$idx');
        return
        '<?php $idx = $_ctx->posts->index()+1; if ('.$expr.'): ?>'.
        $content.
        '<?php endif; unset($idx); ?>';
    }
}

Demonstration of the template cache influence

The following code uses mt_rand(1, 1000) in order to generate a random number between 1 and 1000. In the first function Cache(), the number is generated then directly returned by the function and written as such in the cache. In the second function NoCache(), the number is not stored in the cache : the function is evaluated for every display, thus the number will be different every time.

Important:

If tpl_use_cache is set to false in about:config, these two functions will have the same behavior as nothing will be stored in cache.
$core->tpl->addValue('MTRandCache',array('tplMyTest','Cache'));
$core->tpl->addValue('MTRandNoCache',array('tplMyTest','NoCache'));
 
class tplMyTest
{
    public static function Cache()
    {
        $mt_rand = mt_rand(1, 1000);
 
        return
        '<?php echo(\''.$mt_rand.'\'); ?>';
    }
 
    public static function NoCache()
    {
        return
        '<?php echo(mt_rand(1, 1000)); ?>';
    }
}

Tip:

These functions don't use filters : filters are meant to be used on strings and would have no effect on numbers

The code to add in your template file is :

<p>{{tpl:MTRandCache}} = {{tpl:MTRandNoCache}}</p>

Forcing the refresh of the page (with Ctrl + F5 or Ctrl + R) will change the second number but not the first one.

(Examples are from the plugin myMoreTpl by Kozlika) (Instruction blocks written by Tomtom33).