dmzkrsk
dmzkrsk

Reputation: 2115

Twig tag with some PHP logic within

I'm new in using Twig, but I have a good grab on django templates.

My site is not a Symfony project, but I use Twig as a template language.

What I need is to display a "latest news" block on every page of my site. Putting the logic into an every controller is really not an option.

From my django experience, I was hoping to create a custom tag and render it in my base template. Django has so-called custom "inclusion tags". A tag that performs some python logic and renders its results via another template.

I read about custom tags in Twig. And I successfully created a parser for my shiny new {% latest_news 5 %} tag. But how to execute PHP script in my LatestNews_Node? I read some Twig source code. They use $compiler->write(...) to execute PHP code. Is that the only way to execute custom PHP in tag?

And how to render it via another template and return result at the end?

I tried to look for a working example with no result

Upvotes: 1

Views: 3007

Answers (2)

Saman
Saman

Reputation: 5334

Creating an Extension http://twig.sensiolabs.org/doc/advanced.html#creating-an-extension

How to make a Symfony2 Twig Extension (By Leonard Austin) http://www.leonardaustin.com/blog/technical/how-to-make-a-symfony2-twig-extension/

Upvotes: 0

apfelbox
apfelbox

Reputation: 2634

You are on the wrong way here. You can do what you are trying to do using new tags, but it seems unnecessary.

Just create a new function and call it:

{{ latest_news(5) }}

Example of function code including rendering another template

class MyTwigExtension extends Twig_Extension
{
    public function latest_news ($limit)
    {
        $templateVariables = array(
            'latestNews' => SomeClass::getLatestNews($limit)
        );

        // you would want to make this in a factory / a separate view class
        $loader = new Twig_Loader_Filesystem('/your/template/dir');
        $twig = new Twig_Environment($loader);

        // display actual sub-template
        $template = $twig->loadTemplate('your_existing_template.twig');
        return $template->render($templateVariables);
    }


    public function getFunctions ()
    {
        return array(
            'latest_news' => new Twig_Function_Method($this, 'latest_news', array('is_safe' => array('html')))
        );
    }


    public function getName ()
    {
        return 'my-twig-extension';
    }
}

You now have to create all your Twig instance like this:

$loader = new Twig_Loader_Filesystem('/your/template/dir');
$twig = new Twig_Environment($loader);
$twig->addExtension(new MyTwigExtension());

So I think you might want to either create a factory, which creates the instance for you (with all the dependencies to the extensions) or create a custom View class, which does all that internally.

Upvotes: 6

Related Questions