Latte - evoluce registrace maker a helperů (filtrů) 11/05/2015

Ukážeme si jak registrovat helpery a makra v Nette a Latte. Půjdeme od verze 2.0.6 až, ke dnešnímu dni, do současné verze 2.3.2.

Předpokládejme tedy helper markdown, který bude mít jeden parameter a to vstupní string a makro taktéž markdown.

Nette ~2.0.0

Helpery

V Control nebo v Presenter přetížením metody createTemplate($class = NULL).

function createTemplate($class = NULL)
{
    $template = parent::createTemplate($class);
    $template->registerHelper('markdown', ['Markdown', 'parse']);

    return $template;
}

Makra

V Control nebo v Presenter přetížením metody templatePrepareFilters($template).

function templatePrepareFilters($template)
{
    $latte = new Nette\Latte\Engine();
    MarkdownMacros::install($latte->getCompiler());

    $template->registerFilter($latte);
}

Nette ~2.1.0

Helpery

V Control nebo v Presenter přetížením metody createTemplate($class = NULL).

function createTemplate($class = NULL)
{
    $template = parent::createTemplate($class);
    $template->registerHelper('markdown', ['Markdown', 'parse']);

    return $template;
}

Makra

Do neonu přibyla sekce latte.macros.

nette:
    latte:
        macros: MarkdownMacros::install
        # nebo
        macros: MarkdownMacros

Nette ~2.2.0

Ve verzi 2.2 už přišla větší změna.

Helpery

Buď můžeme použít zase přetížení createTemplate($class = NULL), ale lepší volba je zaregistrovat helpery přímo do LatteFactory.

services:
    nette.latteFactory:
        setup:
            - addFilter('markdown', 'Markdown::parse');
            # nebo
            - addFilter('markdown', ['Markdown', 'parse']);

Můžeme případně využít TemplateFactory, neboť $template->addFilter($name, $callback) se stejně deleguje na Latte.

Makra

Stejně jako tomu bylo ve verzi 2.1.

nette:
    latte:
        macros: MarkdownMacros::install
        # nebo
        macros: MarkdownMacros # install se doplni automaticky

Nette ~2.3.0

Zde je zatím registrace úplně stejná jako v Nette ~2.2.0.


HelperLoader

HelperLoader je od Nette 2.2 deprecated. Registrujeme, jak napovídá dokumentace, jako no-name filter.

Ve verzích 2.2-2.3.

class Helpers
{
    public static function loader($filter, $value)
    {
        if (method_exists(__CLASS__, $filter)) {
            $args = func_get_args();
            array_shift($args);
            return call_user_func_array(array(__CLASS__, $filter), $args);
        }
    }

    public static function markdown($s)
    {
       // ...
    }
}
$latte->registerFilter(NULL, 'Helpers::loader');

Ve verzích 2.0-2.1.

class Helpers 
{
    public static function loader($helper)
    {
        if (method_exists(__CLASS__, $helper)) {
            return new Nette\Callback(__CLASS__, $helper);
        } elseif (isset(self::$helpers[$helper])) {
            return self::$helpers[$helper];
        }
    }

    public static function markdown($s)
    {
       // ...
    }
}
$template->registerHelperLoader('Helpers::loader');

Voláním createTemplate zajistíme, že budeme mít filtry přístupné ve všech šablonách. Ještě by šlo využít v presenteru metody beforeRender, avšak tam se snadno stane, že člověk zapomene zavolat předka, tím pádem by vám filtry mohli fungovat pouze v jedné šabloně.

Metoda templatePrepareFilters je napříč 2.0 až 2.3. Registrování maker je v ní tedy možné pořád. Doporučuji ale využít konfigurace přes neon, je pohodlnější a daleko přehlednější.

Tip: Metoda templatePrepareFilters je volaná jenom 1x, a to při kompilaci šablon. Poté jsou již makra zkompilována a Nette ji nevolá znovu (není potřeba ji volat znovu).