Piste : • jevent
Ceci est une ancienne révision du document !
Table des matières
Jelix et la Communication inter modules ¶
A nugget among so many others contained Jelix, is the internal communication between modules.
But what is this?
Sometimes modules may need to communicate with each other or whether they need information from each other.
Imagine a simple case, an administrative interface that lists the modules (articles, wiki, news), present on his favorite site.
The “Jelixian” solution is to make the administration module communicate with all the others.
The administration module will send a message and retrieve the responses of the modules.
implementation ¶
This page will be made of one template and the responses of modules will be made with the help of Zones (Remind : the Zones are part of page)
So for that, I define a controller “modules” with one action index by default
the controller ¶
class modulesCtrl extends jController { function index() { $rep = $this->getResponse('html'); $tpl = new jTpl(); $tpl->assign('modules',jEvent::notify('HfnuAboutModule')->getResponse()); $rep->body->assign('MAIN',$tpl->fetch('modules')); return $rep; } }
the interesting line of code here is
$tpl->assign('modules',jEvent::notify('HfnuAboutModule')->getResponse());
This line makes 3 things in same time :
- it sends a message named HfnuAboutModule
- it get the data returned by the sent message
- it assigns the data to the variable “modules” of the template.
the following line tell to Jelix, the name of the module, which will display the data :
$rep->body->assign('MAIN',$tpl->fetch('modules'));
le template ¶
<h1>Liste des modules </h1> {if count($modules)} {assign $count = count($modules)} {for $i=0; $i<$count;$i++} <div class="two-cols"> <div class="col"> {$modules[$i]} </div> </div> {/for} {/if}
Bon ok on visualise un peu ce qui va se passer “à la fin” mais comment nos modules “news”,“wiki”,“articles” vont ils répondre à l'evenement HfnuAboutModule ?
A tout jEvent::notify, un listener peut répondre, donc nous allons définir un listener comme suite en 2 temps :
- définition d'un fichier events.xml décrivant le nom de l'évènement et la classe y répondant, events.xml est donc le “liant”
- définition du listener lui-même.
fichier events.xml ¶
<?xml version="1.0" encoding="iso-8859-1"?> <events xmlns="http://jelix.org/ns/events/1.0"> <listener name="hfnuadmin"> <event name="HfnuAboutModule" /> </listener> </events>
On retrouve bien ici le nom de l'évènement HfnuAboutModule auquel le listener hfnuadmin va se charger de répondre
le listener ¶
class hfnuadminListener extends jEventListener{ function onHfnuAboutModule ($event) { $event->add( jZone::get('hfnuadmin~about',array('modulename'=>'hfnuadmin')) ); } }
lorsque HfnuAboutModule est déclenché, alors onHfnuAboutModule entre en oeuvre et répond à l'event (via $event→add())
$event→add() peut recevoir tout type de données. Ici nous lui retournons une zone (que nous avons précédemment abordés dans mes 2 précédants articles) nommée “about”
la zone ¶
class aboutZone extends jZone { protected $_tplname='zone.about'; protected function _prepareTpl(){ $moduleName = $this->param('modulename'); if ($moduleName == '') return; jClasses::inc('havefnubb~modulexml'); $moduleInfo = modulexml::parse($moduleName); $this->_tpl->assign('moduleInfo',$moduleInfo); } }
notre zone ici récupère le paramètre du nom du module, puis parse le fichier module.xml et affecte le résultat au template zone.about
le template ¶
<h1>{$moduleInfo['name']}</h1> <dl> <dt>{@hfnuadmin~hfnuabout.about.version@} :</dt><dd> {$moduleInfo['version']} ({@hfnuadmin~hfnuabout.about.date.create@} {$moduleInfo['dateCreate']})</dd> <dt>{@hfnuadmin~hfnuabout.about.label@} :</dt><dd> {$moduleInfo['label']|escxml}</dd> <dt>{@hfnuadmin~hfnuabout.about.desc@} :</dt><dd> {$moduleInfo['desc']}</dd> <dt>{@hfnuadmin~hfnuabout.about.notes@} :</dt><dd> {$moduleInfo['notes']}</dd> <dt>{@hfnuadmin~hfnuabout.about.licence@} :</dt><dd> {if $moduleInfo['licenceURL'] != ''}<a href="{$moduleInfo['licenceURL']}">{$moduleInfo['licence']}</a>{else}{$moduleInfo['licence']}{/if}</dd> <dt>{@hfnuadmin~hfnuabout.about.copyright@} :</dt><dd> {$moduleInfo['copyright']}</dd> {foreach $moduleInfo['creators'] as $author} <dt>{@hfnuadmin~hfnuabout.about.authors@} :</dt><dd> {if $author['email'] != ''}<a href="mailto:{$author['email']}">{$author['name']|escxml}{else}{$author['name']|escxml}{/if}</a></dd> {/foreach} <dt>{@hfnuadmin~hfnuabout.about.links@}</dt><dd><a href="{$moduleInfo['homepageURL']}">{@hfnuadmin~hfnuabout.about.homepageURL@}</a> - <a href="{$moduleInfo['updateURL']}">{@hfnuadmin~hfnuabout.about.updateURL@}</a></dd> </dl>
Résultat :
Liste des modules
News!
Version :
stable 1.1.2 (du 2008-12-16)
Libellé :
Module de gestion de nouvelles
Description :
Ce module permet de gerer les nouvelles de son site web
Notes :
N/A
License :
GNU General Public Licence
Copyright :
2008 FoxMaSk
Auteurs :
FoxMaSk
Liens :
Page d'accueil du module - Lien mise à jour Wiki
Version :
stable 1.0.2 (du 2009-01-25)
Libellé :
Wiki
Description :
Wiki maison pour la documentation du site web
Notes :
N/A
License :
GNU General Public Licence
Copyright :
2008 FoxMaSk
Auteurs :
FoxMaSk
Liens
Page d'accueil du module - Lien mise à jour
PS : ici je n'ai pas détaillé tous les events.xml des 3 modules ni les 3 listeners mais le code est le même ;)
Conclusion ¶
Voici donc la perle ; qui en quelques petites lignes ; a permis à tous les modules de se “trouver” et réunir des infos au même endroit.
La même mécanique des jEvent::notify() permet par exemple d'enchainer des actions après l'inscription d'un membre (tels que lui envoyer un mail) jEvent::notify() permet également d'enrichir les fonctionnalités d'un module A via d'autres modules B,C,D sans avoir à modifier le module A, etc…