Assignation d'une variable smarty à tous les templates

Added by Nicolas Mathon 4 months ago

Depuis la révision r653 (BackBuilder v3.7), il est désormais possible d’interagir de façon globale sur toutes les instances Smarty et donc d'assigner des variables qui seront disponibles dans tous les smarty des contenus BackBuilder.
Pour cela un nouvel événement a été créé dans la classe LpSmarty : "lpsmarty.do_before_fetch". Cet évènement est déclenché juste avant que la fonction $smarty->fetch() soit lancée. Il est donc possible à cet instant d'interagir sur toutes les variables assignées à l'instance smarty pour en ajouter, en modifier ou en supprimer.

Voici un exemple qui initialise un tableau de pages spéciales qui peuvent être appelées par n'importe quel template pour créer des liens. Le bloc de code suivant est ajouté dans le fichier index.php du site :

 1 BackBuilder::getInstance()->getEventDispatcher()->connect('lpsmarty.do_before_fetch', function (sfEvent $e){
 2     $specialPages = PageTable::getInstance()->selectList()
 3                 ->isOnline()
 4                 ->ofVersionId(BackBuilder::getInstance()->getVersion()->_ID)
 5                 ->whereTypeContenuIds(array(TCROOT_LOGIN, TCROOT_HOME))
 6                 ->getQuery()
 7                 ->orderBy("DATE DESC")
 8                 ->groupBy("TypeContenuID")
 9                 ->getHydratedAll(null, LpDb::HYDRATE_OBJECT, "TypeContenuID");
10     $e->getSubject()->assign("specialPages", $specialPages);
11 });

Le tableau de pages spéciales est ensuite accessible dans n'importe quel template smarty pour créer un lien vers la page de login par exemple :

1 <a href="{$specialPages[$smarty.const.TCROOT_LOGIN]->_urlRewriting}">Login</a>

Attention cependant, dans notre exemple, la requête va être effectuée à chaque appel de template. Ceci n'est pas une bonne pratique car cette requête est assez gourmande. Il est donc recommandé d'utiliser un singleton pour que la requête ne soit effectuée qu'une seule fois par page, ou mieux, de passer par un système de cache :

 1 BackBuilder::getInstance()->getEventDispatcher()->connect('lpsmarty.do_before_fetch', function (sfEvent $e){
 2     if(!$specialPages = apc_fetch("special_pages")){
 3         $specialPages = PageTable::getInstance()->selectList()
 4                     ->isOnline()
 5                     ->ofVersionId(BackBuilder::getInstance()->getVersion()->_ID)
 6                     ->whereTypeContenuIds(array(TCROOT_LOGIN, TCROOT_HOME))
 7                     ->getQuery()
 8                     ->orderBy("DATE DESC")
 9                     ->groupBy("TypeContenuID")
10                     ->getHydratedAll(null, LpDb::HYDRATE_OBJECT, "TypeContenuID");
11         apc_add("special_pages", $specialPages);
12     }
13     $e->getSubject()->assign("specialPages", $specialPages);
14 });

Comments