Nous allons aborder ici la création d’une extension twig, ce qui va nous permettre de créer nos propres filtres ou fonctions et de les utiliser dans nos templates.
Pour l’exemple, j’ai besoin de récupérer l’inverse d’une couleur pour faire un effet du plus mauvais goût, encadrer une div avec l’inverse de sa couleur de fond. Ceci étant dit, il sera facile de créer n’importe quels filtres peut-être plus utiles.
Il peut être intéressant de créer un bundle à cet effet de manière à pouvoir le réutiliser dans tous les projets. Notre bundle va se nommer TuyauTwigBundle. Nous pouvons utiliser le générateur de symfony pour créer l’arborescence mais nous allons ici le faire « à la main » car le nombre de fichier est restreint.
Voici la structure à créer dans notre répertoire src:
Pour commencer, le fichier TuyauTwigBundle.php qui sert à la déclaration de notre bundle. Pas grand chose à en dire, c’est celui que symfony aurait généré si nous l’avions fait avec l’assistant.
<?php namespace Tuyau\TwigBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class TuyauTwigBundle extends Bundle { }
Maintenant le fichier TwigEtension.php. C’est le cœur de notre extension, c’est ici que nous allons définir les fonctions et filtres.
<?php namespace Tuyau\TwigBundle\Twig\Extension; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Bundle\TwigBundle\Loader\FilesystemLoader; class TwigExtension extends \Twig_Extension { public function getName() { return 'tuyautwigext'; } public function getFilters() { return array( 'color_inverse' => new \Twig_Filter_Method($this, 'invertColor'), ); } public function invertColor($color) { $color = trim($color); $prependHash = false; if (strpos($color, '#') !== false) { $prependHash = true; $color = str_replace('#', null, $color); } switch ($len = strlen($color)) { case 3: $color = preg_replace("/(.)(.)(.)/", "\\1\\1\\2\\2\\3\\3", $color); case 6: BREAK; default: trigger_error("Invalid hex length ($len). Must be (3) or (6)", e_user_error); } IF (!preg_match('/[a-f0-9]{6}/i', $color)) { $color = htmlentities($color); trigger_error("Invalid hex string #$color", e_user_error); } $r = dechex(255 - hexdec(substr($color, 0, 2))); $r = (strlen($r) > 1) ? $r : '0' . $r; $g = dechex(255 - hexdec(substr($color, 2, 2))); $g = (strlen($g) > 1) ? $g : '0' . $g; $b = dechex(255 - hexdec(substr($color, 4, 2))); $b = (strlen($b) > 1) ? $b : '0' . $b; return ($prependHash ? '#' : null) . $r . $g . $b; } }
Tout d’abord le namespace en ligne 3.
Puis en ligne 5 et 6 nous importons ce dont nous avons besoin.
Et enfin en ligne 8, la déclaration de notre classe qui doit étendre « Twig_Extension ».
Ensuite, les différentes méthodes.
La première est obligatoire et doit retourner un nom unique permettant de définir notre extension twig. Nous l’appelons « tuyautwigext ».
La méthode « getFilters » va lister les différents filtres que nous allons définir dans notre extension. Ici, un seul filtre qui se nomme « color_inverse » et qui va simplement appeler la méthode « invertColor » avec le paramètre auquel nous appliquerons le filtre.
Enfin la méthode « invertColor » elle même qui va se charger de la transformation de la couleur. Elle recoit une couleur en hexa et retourne son inverse.
Notre filtre est maintenant terminé. Il faut maintenant le rendre disponible grâce à l’injection de dépendance. Nous allons pour cela créer un service. Il est définit dans le fichier « service.yml ».
services: twig.extension.tuyautwigext: class: Tuyau\TwigBundle\Twig\Extension\TwigExtension tags: - { name: twig.extension }
Cette définition de service est chargé par l’intermédiaire du fichier « TuyauTwigExtension.php » du répertoire « DependencyInjection ».
<?php namespace Tuyau\TwigBundle\DependencyInjection; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\Config\FileLocator; /** * This is the class that loads and manages your bundle configuration * * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html} */ class TuyauTwigExtension extends Extension { /** * {@inheritDoc} */ public function load(array $configs, ContainerBuilder $container) { $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.yml'); } }
Ce fichier décrit le chargement de la configuration de notre service à partir du fichier « service.yml ».
Il reste à déclarer notre bundle dans le kernel (app/AppKernel.php).
new Tuyau\TwigBundle\TuyauTwigBundle(),
Voilà, notre filtre est à présent disponible dans nos template au même titre que les filtres par défaut. Voici un exemple de l’utilisation de notre filtre:
<div style="width:150px; height:150px; background-color:#ffddaa; border: 5px solid #{{'ffddaa'|color_inverse}}"></div>
Dans mon cas, les valeurs des couleurs proviennent de la base de données ce qui donne un peu plus de sens à l’utilisation de ce magnifique filtre.
Merci Pascal
Salut !Il a l’air bien ce Framework, j’he9site entre CakePHP, Zend Framewprk et Symphony ?Les livres Symphony, on peut les treuvor sur tout bon site d’e-commerce ?
Toute la doc est sur symfony.com !
En plus la traduction francaise est dispo pour les anglophyles ! 😉
anglophobes*
très bon tuto!
J’ai déjà essayer mais il y à deux problème :
– $definition = new Definition(‘Tuyau\TwigBundle\Extension\MyTwigExtension’); de la class DependencyInjection
– Tuyau\TwigBundle\Twig\Extension\MyTwigExtension du services.yml
est ce que les deux ne devrais pas être le même et la class est TwigExtension mais non pas MyTwigExtension?
C’est corrigé!!! Un copier/coller trop rapide…
Bonjour,
apres la creation d’un bundle twigbundle dans le src j’ai cette erreur :
InvalidArgumentException: There is no extension able to load the configuration for « twig.extension.ecommercetwigext » (in Projet/Symfony2/src/Ecommerce/TwigBundle/DependencyInjection/../Resources/config/services.yml). Looked for namespace « twig.extension.ecommercetwigext », found none
merci d’avance