Doctrine entities in Twig templates

By | January 30, 2013

In a Symfony2 project, Doctrine entities can be used inside Twig templates with the help of Twig extensions.

The example works with the standard Symfony2 installation and the AcmeDemoBundle, and it is supposed to add a set of links on one of the demo pages. Each link represents a color, while the HEX code for that color is displayed when the link is clicked. The colors are retrieved from the database.

The example is using Twig functions, but an alternative which is using global variables is also presented.

The Doctrine entity:

// src/Acme/DemoBundle/Entity/Color.php

namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="color")
 */
class Color
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=8)
     */
    protected $hex;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Color
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set hex
     *
     * @param string $hex
     * @return Color
     */
    public function setHex($hex)
    {
        $this->hex = $hex;

        return $this;
    }

    /**
     * Get hex
     *
     * @return string
     */
    public function getHex()
    {
        return $this->hex;
    }
}

This entity has a basic structure which should store the name and HEX code for a color.

The Twig extension:

// src/Acme/DemoBundle/Twig/Extension/ColorExtension.php

namespace Acme\DemoBundle\Twig\Extension;

/**
 * Custom Twig extension used to retrieve the colors.
 */
class ColorExtension extends \Twig_Extension
{
    /**
     * @var EntityManager
     */
    protected $em;

    public function __construct($em)
    {
        $this->em = $em;
    }

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

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

    public function getColors()
    {
        return $this->em->getRepository('AcmeDemoBundle:Color')->findAll();
    }
}

The following list contains the most important remarks related to the Twig extension:

  • The string returned by the “getName” ┬ámethod – “color_extension” will be used to register the extension;
  • The “getColors” method is the one which returns the entities, using the EntityManager;
  • In order to have access to the EntityManager, the Twig extension needs to be registered by specifying that the EntityManager service (identified as “doctrine.orm.entity_manager”) will be passed as argument;
  • The key “get_colors” from the array returned by the “getFunctions” method is the actual Twig function name which needs to be called in the Twig template to return the entities.

Twig extension registration:

In order to register the Twig extension the following piece of code needs to be added to src/Acme/DemoBundle/Resources/config/services.xml:

<service id="twig.extension.acme.demo_bundle.color_extension" class="Acme\DemoBundle\Twig\Extension\ColorExtension">
    <tag name="twig.extension" />
    <argument type="service" id="doctrine.orm.entity_manager" />
</service>

As previously mentioned, the “color_extension” string is used in the service id and the EntityManager service is sent as parameter for the Twig extension.

Everything should be set by now, the only thing that needs to be done is to call the “get_colors” function inside a Twig template. Here’s an example:

{% set colors = get_colors() %}
{% for color in colors %}
   <a href="javascript:alert('{{color.hex}}'); return false;">{{color.name}}</a>
{% endfor %}

The global variables alternative.

Update the Twig extension (src/Acme/DemoBundle/Twig/Extension/ColorExtension.php) with the following code:

public function getGlobals()
{
    return array('colors' => $this->getColors());
}

This means that the “colors” key will become a global variable and can be used in a Twig template.

{% for color in colors %}
    <a href="javascript:alert('{{color.hex}}'); return false;">{{color.name}}</a>
{% endfor %}

7 thoughts on “Doctrine entities in Twig templates

  1. cbtraize

    Hello

    I have a problem in symfony2

    ContextErrorException: Catchable Fatal Error: Argument 1 passed to GG\UserBundle\Twig\UserExtension::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in /var/www/clients/client1/web1/web/symfony/app/cache/dev/appDevDebugProjectContainer.php on line 1603 and defined in /var/www/clients/client1/web1/web/symfony/src/GG/UserBundle/Twig/UserExtension.php line 13

    My Twig Extends :
    em = $em;
    $this->conn = $em->getConnection();
    }
    public function getFunctions()
    {
    return array(
    ‘geekInscrits’ => new \Twig_Function_Method($this, ‘nbGeekInscrits’),
    );
    }
    public function nbGeekInscrits()
    {
    $sql = ‘COUNT(*) FROM GG_User’;
    return $this->conn->fetchAll($sql);
    }

    public function getName()
    {
    return ‘gguser_extension’;
    }
    }

    ?>

    # twig extension
    services:
    my.twig.extension:
    class: GG\UserBundle\Twig\UserExtension
    arguments:
    em: “@doctrine.orm.entity_manager”
    tags:
    – { name: twig.extension }

    Can you help me ?

    Thanks you very much

  2. cbtraize

    Excuse me this is my twig class :

    namespace GG\UserBundle\Twig;
    use Doctrine\ORM\EntityManager;

    class UserExtension 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(
    ‘geekInscrits’ => new \Twig_Function_Method($this, ‘nbGeekInscrits’),
    );
    }
    public function nbGeekInscrits()
    {
    $sql = ‘COUNT(*) FROM GG_User’;
    return $this->conn->fetchAll($sql);
    }

    public function getName()
    {
    return ‘gguser_extension’;
    }
    }

  3. Cristian Radulescu Post author

    The services are not defined correctly. the arguments for your Twig extension should be like:
    arguments: ["@doctrine.orm.entity_manager"]

  4. Michelle

    big ths for this example, he helped me ­čÖé

  5. Andrei

    Salutari! Dupa ore intregi de chin am dat peste articolul asta.
    Mersi mult!

Leave a Reply