marysmech
marysmech

Reputation: 323

twig inheritance and symfony2 controller variables

Im trying my first project using symfony2 + twig. I created basic twig template with defined blocks. It basically looks like this

{% block content %}
  some content...
{% endblock %}

{% block footer %}
  {{ footer.content}}
{% endblock %}

I want footer to be same for all pages. Footer is loaded from DB and its set in controller. I wanted inherit from template described above to other pages but I have to always set footer in controller otherwise variable is not defined.

My questions is if exists any 'nice' way how to set footer variable for multiple templates inherited from parent template?

Upvotes: 3

Views: 820

Answers (2)

hoangthienan
hoangthienan

Reputation: 866

you can do with one of the following, 'write a custom Twig Extension'

<?php

namespace AppBundle\Extension;

class MyTwigExtension extends \Twig_Extension
{
    private $em;
    private $conn;

    public function __construct(\Doctrine\ORM\EntityManager $em) {
        $this->em = $em;
        $this->conn = $em->getConnection();
    }

    public function getFunctions()
    {
        return array(
            'users' => new \Twig_Function_Method($this, 'getUsers'),
        );
    }

    public function getUsers()
    {
        $sql = "SELECT * FROM users ORDER BY accountname";
        return $this->conn->fetchAll($sql);
    }

    public function getName()
    {
        return 'smproc4_twig_extension';
    }
}

Register an Extension as a Service

services:
    my.twig.extension:
        class: AppBundle\Extension\MyTwigExtension
        tags:
            - { name: twig.extension }
        arguments:
            em: "@doctrine.orm.entity_manager"

Using the custom Extension

Hello {{ name }}!
<ul>
{% for user in users() %}
    <li>{{ user.accountname }}</li>
{% endfor %}
</ul>

have a look at the

How to Write a custom Twig Extension

Creating an Extension

Upvotes: 0

zilongqiu
zilongqiu

Reputation: 846

The solution : Embedding Controllers

In some cases, you need to do more than include a simple template. Suppose you have a sidebar in your layout that contains the three most recent articles. Retrieving the three articles may include querying the database or performing other heavy logic that can't be done from within a template.

The solution is to simply embed the result of an entire controller from your template. First, create a controller that renders a certain number of recent articles:

Controller

// src/AppBundle/Controller/ArticleController.php
namespace AppBundle\Controller;
// ...

class ArticleController extends Controller
{
    public function recentArticlesAction($max = 3)
    {
        // make a database call or other logic
        // to get the "$max" most recent articles
        $articles = ...;

        return $this->render(
            'article/recent_list.html.twig',
            array('articles' => $articles)
        );
    }
}

View

{# app/Resources/views/article/recent_list.html.twig #}
{% for article in articles %}
    <a href="/article/{{ article.slug }}">
        {{ article.title }}
    </a>
{% endfor %}

Layout

{# app/Resources/views/base.html.twig #}

{# ... #}
<div id="sidebar">
    {{ render(controller(
        'AppBundle:Article:recentArticles',
        { 'max': 3 }
    )) }}
</div>

Upvotes: 7

Related Questions