====== Creation of Generic "Jelix" Modules (part 1/2) ====== ===== Description ===== A generic module A generic module can take various forms, a ''simple''business class, or a larger one with a zone for example. This allows the integration of modules in any application Jelix. To illustrate these two aspects, I will take two examples: - [[http://bitbucket.org/foxmask/jblog/src/tip/jblog/modules/jtags/|the module jTags of the application ShareCode]] permits to tag various things : posts, photos, movies, etc... - [[https://bitbucket.org/foxmask/havefnubb/src/tip/havefnubb/modules/hfnurates/|the module HfnuRates of the application HaveFnuBB]] * The first case permits to save the tags when creating a topic * the second case permits to save a "note" of appreciation of a discussion (after its creation, of course) ===== Introduction ===== * j'appelle module "générique" le module offrant un service ; * j'appelle module "utilisateur" le module exploitant ledit service. ===== PREMIER VOLET : jTags ===== ==== INGREDIENTS ==== - un form - un template - un contrôleur - une classe métier - une zone Je possède un module de forum listant des pages de discussion et j'ai envi de permettre aux membres de tagger celles-ci. Disposant déjà d'un "[[http://docs.jelix.org/en/manual-1.1/jforms|form]]" Jelix pour gérer les données de ma discussion (posts.form.xml), j'ajoute à ce dernier, un noeud "textarea" nommé "tag", comme suit : ==== FORM ====
[...]
Ainsi paré, à présent mon module discussion dispose d'un textarea "tags" en plus du titre et du contenu. **TIPS** Le contenu de la propriété "locale" permet d'internationaliser les libellés du formulaire. ==== LE TEMPLATE edit ==== Voyons maintenant comment est présenté le template **edit** à l'utilisateur : {form $form, 'havefnubb~posts:save', array('id_post'=>$id_post)}

{ctrl_label 'subject'}

{ctrl_control 'subject'}

{ctrl_label 'tags'}

{ctrl_control 'tags'}

{ctrl_label 'message'}

{ctrl_control 'message'}

{formsubmit 'validate'} {formreset 'cancel'}
{/form}
* $form est l'instance de mon formulaire Jelix, suivent, l'action à effectuer (havefnubb~posts:save) et les paramètres à passer quand les données sont soumises. * les {ctrl_control xxx} affichent les champs définis dans posts.form.xml ==== LE CONTROLEUR ==== A présent le contrôleur ci-dessous nous montre comment est instancié le formulaire @@F@$form@@ dans la méthode **edit**, et ce qui se produit quand le formulaire est enregistré (methode **save**) class postsCtrl extends jController { //let's init the form function edit() { $id_post = $this->intParam('id_post'); $srvTags = jClasses::getService("jtags~tags"); $tags = implode(',',$srvTags->getTagsBySubject('forumscope', $id_post)); // new instance of jForms $form = jForms::create('havefnubb~posts',$id_post); // initiate the data from the dao "posts" $form->initFromDao("havefnubb~posts"); // set the tags data to the form $form->setData('tags', $tags); $rep = $this->getResponse('html'); $tpl = new jTpl(); $tpl->assign('id_post', $id_post); $tpl->assign('form', $form); [...] // let's display the form return $rep; } //let's save the datas function save() { $id_post = $this->intParam('id_post'); //get the instance of a previous jForms::create() $form = jForms::fill('havefnubb~posts',$id_post); // get the posted data $tags = explode(",", $form->getData("tags")); //call the class jTags and give the data to store jClasses::getService("jtags~tags")->saveTagsBySubject($tags, 'forumscope', $id_post); // destroy the instance jForms::destroy('havefnubb~posts', $id_post); $rep = $this->getResponse('html'); [...] $rep->action ='havefnubb~posts:view'; // let's go to the view page return $rep; } function view () { [...] } } ==== LA CLASSE ==== la classe métier de jTags s'occupe de gérer les données soumises via les 2 méthodes edit/save du contrôleur ci dessus. class tags { function getTagsBySubject($scope, $id) { //read the table and retreive the datas [...] } function saveTagsBySubject($tags, $scope, $id) { //save the datas submitted [...] } } Pour que la "magie" opère nous stockons donc dans la table du module "générique", les variables @@P@$scope@@ et @@P@$id@@ qui permettent de relier les "Tags" à la "Discussion". ==== ZONE ==== Pour parachever le tout nous disposons d'une zone listant la totalité du nuage de tags, utilisable depuis le template de son choix comme suit : {zone "jtags~tagscloud",array('destination'=>'havefnubb~default:cloud')} ici ''destination'' permet lors du clique sur un tag, d'indiquer à jelix, vers quelle action envoyer l'utilisateur ===== Conclusion ===== Grâce à la souplesse du module jTags, il suffit de 2 points d'attache entre le module Forum et le module jTags pour permettre au premier d'exploiter le second ici les points d'attache entre le module "utilisateur" et le module "générique" sont : * le textarea qui fait apparaitre le champ tags dans le formulaire * la classe tags appelée depuis les méthodes du contrôleur Suite : [[fr:tutoriels:modules:generic2|Création de module génériques (2/2)]]