Créer un module POLYMOD.

Il serait très long et peu explicite de décrire la totalité des fonctionnalités offertes, nous allons pour le moment prendre un exemple concret de module pour expliquer le fonctionnement. Il est ensuite possible de l’adapter à vos besoins réels pour réaliser votre propre application. Pour cet exemple, nous allons créer un module de gestion documentaire un peu plus simple que la Médiathèque présente dans la démo d'Automne.

ATTENTION : Certaines opérations ne peuvent être modifiées une fois effectuée. De même, un module ne peut être supprimé une fois créé. Il est donc préférable d’utiliser une version démo d’Automne pour faire des essais plutôt que de commencer directement à créer votre module sur un site en ligne.


Le module de gestion documentaire permet de gérer des fichiers de type Word, PDF, etc. au travers de votre site. Il permet de catégoriser ces fichiers comme vous le souhaitez, d’y associer des droits (de visibilité ou de modification) et d’avoir un point central de contrôle de tous les fichiers mis à disposition sur votre site quelque soit l’endroit ou vous les emploierez ensuite.

Création du module :

Dans la section "Administration > Gestion des modules" cliquez sur « Nouveau ».

Vous pourrez ainsi ajouter une nouvelle application. Donnez un nom à cette application ainsi qu’un identifiant (codename). Cet identifiant sera employé par Automne pour désigner de façon unique votre module. Il ne doit donc pas avoir déjà été utilisé. Veillez à le choisir de façon adéquate car il ne pourra pas être modifié ensuite. Nous allons donc créer un module ayant comme identifiant pdocs (par convention, « p » pour Polymod, puis docs pour « documents ») et comme nom « Gestion documentaire ».

Création de la structure des objets :

Une fois créé, le module attend la création des objets le composant. Un objet servant de réceptacle aux champs élémentaires dont nous avons parlé plus haut. Chaque objet possède un nom, une description un statut de ressource (voir l’explication sur la page adéquate d’Automne). D’autres options sont disponibles pour ces objets mais nous en verrons le détail plus tard.

 
 
ATTENTION : Tous les paramètres d’un objet sont modifiable ultérieurement à l’exception du statut de ressource, veillez donc à bien le choisir dès la création de l’objet.
 
Pour notre exemple nous n’avons besoin que d’un seul type d’objet : l’objet « Document » qui stockera le fichier ainsi qu’un ensemble de méta données relatives à ce fichier. Cet objet sera de type « ressource primaire » car nous souhaitons que son contenu ne soit visible en ligne que suite à sa validation par un utilisateur possédant les privilèges adéquat (bien entendu ce point est à définir en fonction de votre besoin). De plus le fait d’être une ressource primaire permet à l’objet d’avoir automatiquement des dates de publications ce qui peut-être utile pour publier ou dépublier des documents à des dates données.

Il est donc maintenant nécessaire de définir précisément quels seront les champs élémentaires composant notre objet « Document »

Commençons par son titre. Nous allons créer un nouveau champ et choisir dans la liste déroulante quel type d’élément sera utilisé pour ce champ. Ici, un champ de type « chaîne de caractère » semble convenir car nous souhaitons n’avoir qu’une simple labellisation du document sans mise en forme. Suite à ce choix, un formulaire apparaît permettant de définir précisément le champ : Titre, description (facultatif) suivit de paramètres propres au champ définit (longueur maximum : 255 caractères et la vérification sur l’email qui permet dans d’autres cas de vérifier que la valeur saisie est bien un email valide). Pour finir, 3 cases à cocher permettent de spécifier des options particulières pour le champ :
  • Est il obligatoire. Dans le cas d’un titre, on peut estimer que oui, sa saisie est nécessaire.
  • Ajouter au formulaire de recherche. Dans l’administration du module, permet d’utiliser ce champ lors des recherches par mot clé ou de proposer une liste déroulante pour les objets composés. Dans le cas présent, cette case est à cocher car le titre est un élément à prendre en compte dans les recherches.
  • Visible dans les résultats d’une recherche. Ce paramètre permet de définir les champs importants que vous souhaitez voir apparaître dans les résultats des recherches que vous effectuerez sur vos documents dans l’administration du module. Le titre en tant que 1er champ de l’objet est obligatoirement visible, inutile donc de cocher cette case ici.


Une fois ces différents paramètres sélectionnés, validez la création de votre champ pour passer au suivant.

ATTENTION : Tous les paramètres d’un champ sont modifiable ultérieurement à l’exception de son type, veillez donc à bien le choisir dès la création de l’objet.


Suite au titre, nous créerons 4 champs supplémentaires :

  • Un champ catégorie, permettant de catégoriser les différents fichiers gérés par le module. Deux options importantes pour ce type de champ : les catégories multiple (permet d’associer une seule catégorie ou plusieurs pour notre fichier), ici plusieurs catégories pour un même document semble justifié. La catégorie de plus haut niveau parmet de spécifier (une fois des catégories crées dans l’administration du module) d’en choisir une comme racine pour ce champ. Ce peut-être très utile dans le cas ou plusieurs champs sont de type catégorie pour un même objet donné.
  • Un champ langue (peut-être omis dans le cas ou le multilinguisme ne fait pas parti de votre besoin.
  • Un champ description au format texte (avec mise en forme HTML) permettra de décrire plus précisément le document.
  • Enfin le champ fichier à proprement parler qui permettra d’importer le fichier Word, PDF, etc. qui sera associé à l’objet document que nous avons créé.

Gestion des documents, administration du module :

Une fois la création de la structure des différents objets terminés, vous pouvez commencer la saisie du contenu du module via la liste des applications au même titre que tout module existant.

L’administration du module est construite automatiquement en fonction de la structure des différents objets que vous aurez créé.

Saisissez si besoin un ensemble de catégories (pensez suite à la création de la première catégorie à vous donner les droits d’accès à cette catégorie dans votre profil) puis vous pouvez créer / rechercher / modifier / supprimer / valider vos objets coté administration du site. Au besoin vous pouvez éditer les propriétés de vos objets si certains détails sont à peaufiner.

Il est aussi possible d’ajouter des champs si certains se révèlent manquant. Vous pouvez aussi supprimer des champs.

ATTENTION : En supprimant un champ, vous perdrez toutes les données déjà saisies pour ce champ.


Lorsque vous jugez que le coté administratif du module convient à votre besoin, vous pouvez penser à la manière dont vous souhaitez afficher les informations fournies par le module coté publique du site.

Affichage du module coté public :

3 possibilités s’offrent à vous pour afficher vos données provenant du module sur le site publique géré par Automne :

  • Création de rangée de contenu :
    Une rangée de contenu est la méthode la plus souple et la plus complète pour insérer le contenu du module dans votre site. En effet, vous pouvez de cette manière spécifier complètement l’affichage du contenu ainsi que le moteur de recherche le cas échéant.
  • Création d’un plug-in pour l’éditeur visuel (WYSIWYG) :
    Un plug-in pour l’éditeur visuel (WYSIWYG) vous permet d’insérer dans vos textes mis en forme un ou plusieurs éléments provenant du module tout en gardant une liaison entre l’élément du module et son affichage : la suppression, la péremption des dates de publication ou l’absence de droits sur l’objet le feront automatiquement disparaître de l’endroit ou vous l’avez inséré pour être remplacé par ce que vous souhaitez (texte explicatif ou même un simple vide.
  • Création de fils RSS :
    Un fils RSS est généralement complémentaire de l’une des deux autres méthodes d’affichage cité plus haut. Cela permet à vos internautes de pouvoir suivre simplement l’ajout de nouveaux contenus pour un module donné (par exemple un module d’actualité ou un module de blog).


Bien entendu ces 3 méthodes d’affichages sont complémentaires les unes des autres et il est tout à fait possible de les combiner les unes aux autres pour un module donné.
Nous nous contenterons dans cet exemple de créer une rangée de contenu pour le module documents. En effet les deux autres méthodes d’affichages (plug-in pour l’éditeur visuel et fils RSS) respectent les mêmes principes et de plus, la démo d’Automne 3.3.0 présente deux exemples de plug-in pour l’éditeur visuel pour le module « Gestion documentaire » et un exemple de fil RSS pour le module « Actualités ». N’hésitez pas à vous y référer en cas de besoin ou bien de poser vos questions à ce sujet sur le forum.

Création d’une rangée de contenu :

Pour créer une rangée de contenu, allez dans la section « Modèles » d’Automne puis sur l’onglet « Bibliothèque de rangées ». Créez une nouvelle rangée vous ouvrira un zone de texte dans laquelle vous pourrez créer ici le code XHTML / XML nécessaire.

ATTENTION : Il est nécessaire de parfaitement maîtriser XHTML et CSS pour pouvoir créer correctement une rangée de contenu pour votre site.


Saisissez un nom pour votre rangée reflétant son utilité. Par exemple nous allons créer ici un moteur de recherche pour afficher les divers documents du module, ce nom pourrait donc être « Gestion documentaire : Recherche ».
Il est important ici de comprendre les différents concepts nécessaires à la création d’une rangée. Un certain nombre d’étapes sont à réaliser au fur et à mesure.

Pour commencer, l’ensemble des tags XML disponibles pour un module sont détaillés en dessous de la zone de saisie de la rangée.

Cette aide dynamique vous listera tous les différents éléments que vous pouvez employer en fonction de la structure que vous avez donné au module.

Sélectionnez dans l’aide du module la syntaxe des « Blocs de données », vous obtiendrez le détail concernant le tag <block> qui doit contenir l’ensemble des tags relatif à votre module (une rangée pouvant accueillir des blocs de plusieurs modules différents).
C’est donc par ce tag que vous devez commencer votre rangée avant toute chose.
Dans ce tag, nous allons ensuite coder un formulaire qui servira à lancer une recherche sur les documents du module. A ce niveau, vous pouvez saisir un simple formulaire en XHTML contenant un champ texte (pour la recherche par mots clé) suivi par exemple d’une liste déroulante pour pouvoir sélectionner les documents par catégorie pour conclure notre formulaire nous allons bien sur ajouter un bouton de validation.

Le code ressemble maintenant à quelque chose comme cela :

<row>
    <block module="pdocs" id="docssearch" language="fr">
        <div id="docssearch">
            <form action="" method="get">
                <h3>Rechercher des documents : </h3>
                <label for="keyword">Mots Clés : </label><br /><input type="text" id="keyword" name="keyword" value="" /><br />
                <label for="cat">Catégorie : </label><br />
                <select id="cat" name="cat">
                    <option value=""> </option>
                </select>
                <br /><br />
                <input type="submit" class="button" name="search" value="Rechercher" />
            </form>
        </div>
    </block> 
</row>

Maintenant il nous faut préciser sur quelle adresse doit se soumettre le formulaire, dans notre cas nous souhaitons qu’il affiche la même page. Dans l’aide, consultez la partie « Variables générales » vous y trouverez la syntaxe des variables relative aux pages.
Toutes les variables, relatives à l’environnement ou bien aux objets que vous allez manipuler sont entourées par deux accolades.
Dans notre cas nous souhaitons avoir l’adresse de la page en cours dans l’attribut action du tag <form> ce qui se traduit par {page:self:url}.
Nous souhaitons aussi que le formulaire conserve les données qui y ont été saisies pour la recherche lorsqu’il se réaffiche. Dans le champ texte nous allons donc remplir l’attribut value avec la variable {request:string:keyword}. Enfin, nous souhaitons que le tag <select> affiche l’ensemble des catégories relatives aux documents. Pour se faire, dans l’aide, nous allons sélectionner le champ « Catégories » appartenant à l’objet « Document ». Nous obtenons ici l’ensemble des variables et fonctions disponibles pour ce champ particulier. L’une des fonctions disponible est spécifiquement prévue pour répondre à ce besoin : la fonction « selectOptions ».
Le formulaire a maintenant cette forme :

<row>
    <block module="pdocs" id="docssearch" language="fr">
        <div id="docssearch">
            <form action="{page:self:url}" method="get">
                <h3>Rechercher des documents : </h3>
                <label for="keyword">Mots Clés : </label><br /><input type="text" id="keyword" name="keyword" value="{request:string:keyword}" /><br />
                <label for="cat">Catégorie : </label><br />
                <select id="cat" name="cat">
                    <option value=""> </option>
                    <atm-function function="selectOptions" object="{Document:Categories}" selected="{request:int:cat}">
                </select>
                <br /><br />
                <input type="submit" class="button" name="search" value="Rechercher" />
            </form>
        </div>
    </block> 
</row>


Une fois le formulaire de recherche préparé, il faut maintenant récupérer et interpréter les valeurs qu’il envoie, lancer une recherche sur ces données et afficher les résultats correspondants.

Pour se faire, nous allons créer un moteur de recherche. La notion de recherche est très importante dans la création d’une rangée. En effet, la plus grande partie des opérations d’affichage des éléments des modules consiste à les rechercher avec un certain nombre de critères puis à les afficher d’une certaine manière.

Comment appréhender correctement cette recherche ? Prenons un exemple simple : Imaginez un champ patates. Ce champ est composé de centaines de patates de différentes formes, catégorie, poids, taille, forme, etc.
Vous souhaitez rechercher dans ce champ des patates répondant à un certain nombre de critères.

Notre recherche va donc s’effectuer de la manière suivante :

  1. Nous cherchons des patates
  2. Nous voulons que ces patates répondent aux critères suivants (par exemple) :
    • Une taille donnée
    • Une forme donnée
  3. Sur l’ensemble de patates répondant aux critères ci-dessus, nous souhaitons trier les résultats par taille de patate croissante.
  4. Enfin, nous souhaitons avoir les 30 premières patates répondant à cet ensemble de critères.

Donc pour résumer, une recherche se compose de 3 grandes étapes :

  • Définir ce qui est recherché,
  • Définir un ensemble de critères à respecter pour les résultats,
  • Définir comment présenter ces résultats (tri et nombre de résultats à renvoyer).

Revenons maintenant à notre exemple initial : la recherche de documents. Dans cet exemple, nous allons donc rechercher des documents et les filtrer par mot-clé et / ou par catégorie.

Pour ce faire, dans l’aide, consultez la partie « Effectuer une recherche » vous y trouverez la syntaxe des différents tags relatif à cette tache. Nous commencerons par définir la création d’une nouvelle recherche et y spécifier les deux critères limitant pouvant provenir du formulaire créé plus haut. Cela nous donne un code de ce type :

<atm-search what="{Document}" name="docsresult">
    <atm-search-param search="docsresult" type="{Document:Categories:fieldID}" value="{request:int:cat}" mandatory="false" />
    <atm-search-param search="docsresult" type="keywords" value="{request:string:keyword}" mandatory="false" />
    <atm-result search="docsresult">
        ...
    </atm-result>
    <atm-noresult search="docsresult">
        ...
    </atm-noresult>
</atm-search>


Le tag <atm-search> défini la recherche, les tags <atm-search-param> définissent les filtres (optionnels) à appliquer sur cette recherche et les tags <atm-result> et <atm-noresult> définissent respectivement l’affichage des résultats et l’affichage dans le cas ou il n’y a aucun résultat.

Concernant l’affichage des résultats maintenant. Le tag <atm-result> sera lu pour chaque résultat trouvé par la recherche. Il faut donc dans ce tag détailler l’aspect de l’affichage d’un document en se servant de tags XHTML classqiues pour la mise en forme, de tags de « Travail » pour spécifier des règles propres au résultat à afficher ainsi que des variables des champs des documents. Ceci peut donc nous donner le code suivant :

<div class="title">{Document:formatedDateStart|d/m/Y} - {Document:label}</div>
<div class="cat">
    <atm-loop on="{Document:Categories:values}">
        <a href="{page:self:url}?cat={Document:Categories:values:id}" title="Voir les documents de la catégorie '{Document:Categories:values:label}'">{Document:Categories:values:label}</a>
        <atm-if what="!{lastloop}">, </atm-if>
    </atm-loop>
</div>
<atm-if what="{Document:Description:value}">{Document:Description:value}</atm-if>
<atm-if what="{Document:Fichier:fileIcon}"><img src="{Document:Fichier:fileIcon}" alt="{Document:Fichier:fileExtension}" title="{Document:Fichier:fileExtension}" /> </atm-if>{Document:Fichier:fileHTML} - {Document:Fichier:fileSize}Mo
<hr />


Notez le tag <atm-loop> permettant d’afficher les différentes catégories du document ainsi qu’un lien permettant de relancer une recherche sur cette catégorie de documents. De même, notez la vérification à l’aide du tag <atm-if> sur la présence d’une icône associée au type de fichier avant d’afficher cette icône (dans le cas où elle existe). Idem pour l’affichage de la description du document.

La rangée est pratiquement terminée, il reste à ajouter :

  • Un message dans le tag <atm-noresult> pour spécifier qu’aucun résultat n’a été trouvé :

<atm-noresult search="docsresult">Aucun résultat trouvé pour votre recherche ...</atm-noresult>

  • L’affichage du nombre de résultats trouvés avant l’affichage du premier résultat :

<atm-if what="{firstresult}">{maxresults} résultat(s) pour votre recherche</atm-if>

  • Un système de pagination des résultats à afficher après le dernier résultat de la page :

<atm-if what="{lastresult}">
    <div class="pages">
        <atm-function function="pages" maxpages="{maxpages}" currentpage="{currentpage}" displayedpage="5">
            <pages><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">{n}</a> </pages>
            <currentpage><strong>{n}</strong> </currentpage>
            <previous><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">&lt;</a> </previous>
            <next><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">&gt;</a> </next>
        </atm-function>
    </div>
</atm-if>


Et pour que cette pagination soit correctement prise en compte par le moteur de recherche, il faut lui ajouter juste avant le tag <atm-result> deux tags permettant de spécifier la page à afficher et le nombre de résultats par page :

<atm-search-limit search="docsresult" value="10" />
<atm-search-page search="docsresult" value="{request:int:page}" />


Une fois tout ceci aggloméré, nous obtenons le code suivant pour la rangée documents :

<row>
    <block module="pdocs" id="docssearch" language="fr">
        <!--Search form-->
        <div id="docssearch">
            <form action="{page:self:url}" method="get">
                <h3>Rechercher des documents : </h3>
                <label for="keyword">Mots Clés : </label><br /><input type="text" id="keyword" name="keyword" value="{request:string:keyword}" /><br />
                <label for="cat">Catégorie : </label><br />
                <select id="cat" name="cat">
                    <option value=""> </option>
                    <atm-function function="selectOptions" object="{Document:Categories}" selected="{request:int:cat}">
                </select>
                <br /><br />
                <input type="submit" class="button" name="search" value="Rechercher" />
            </form>
        </div>
        <!--Search documents-->
        <div id="docsresult">
            <atm-search what="{Document}" name="docsresult">
                <!--Search Filters-->
                <atm-search-param search="docsresult" type="{Document:Categories:fieldID}" value="{request:int:cat}" mandatory="false" />
                <atm-search-param search="docsresult" type="keywords" value="{request:string:keyword}" mandatory="false" />
               
                <!--Results per pages and page to search-->
                <atm-search-limit search="docsresult" value="10" />
                <atm-search-page search="docsresult" value="{request:int:page}" />
   
                <!--Displaying results-->
                <atm-result search="docsresult">
                    <!--Display results number on first result-->
                    <atm-if what="{firstresult}">{maxresults} résultat(s) pour votre recherche</atm-if>
                   
                    <!--Display a result-->
                    <div class="title">{Document:formatedDateStart|d/m/Y} - {Document:label}</div>
                    <div class="cat">
                        <atm-loop on="{Document:Categories:values}">
                            <a href="{page:self:url}?cat={Document:Categories:values:id}" title="Voir les documents de la catégorie '{Document:Categories:values:label}'">{Document:Categories:values:label}</a>
                            <atm-if what="!{lastloop}">, </atm-if>
                        </atm-loop>
                    </div>
                    <atm-if what="{Document:Description:value}">{Document:Description:value}</atm-if>
                    <atm-if what="{Document:Fichier:fileIcon}"><img src="{Document:Fichier:fileIcon}" alt="{Document:Fichier:fileExtension}" title="{Document:Fichier:fileExtension}" /> </atm-if>{Document:Fichier:fileHTML} - {Document:Fichier:fileSize}Mo
                    <hr />
                   
                    <!--Display pagination on last result-->
                    <atm-if what="{lastresult}">
                        <div class="pages">
                            <atm-function function="pages" maxpages="{maxpages}" currentpage="{currentpage}" displayedpage="5">
                                <pages><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">{n}</a> </pages>
                                <currentpage><strong>{n}</strong> </currentpage>
                                <previous><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">&lt;</a> </previous>
                                <next><a href="{page:self:url}?cat={request:int:cat}&amp;keyword={request:string:keyword}&amp;page={n}">&gt;</a> </next>
                            </atm-function>
                        </div>
                    </atm-if>
                   
                </atm-result>
               
                <!--No results to display-->
                <atm-noresult search="docsresult">Aucun résultat trouvé pour votre recherche ...</atm-noresult>
            </atm-search>
        </div>
    </block> 
</row>


Et vous pouvez faire évoluer cette rangée de la manière qui répond le mieux à votre besoin. Vous pouvez aussi - comme dans la démo - scinder cette rangée en deux rangées distinctes (une partie « formulaire de recherche », l’autre partie « affichage des résultats ») pour répondre à un besoin particulier de mise en page.

Conclusion :

Cet exemple pourrait être bien plus détaillé mais l’essentiel des concepts du système sont décrit ci-dessus. Vous trouverez dans la section suivante de cette documentation un ensemble d’exemples d’utilisation que nos avons mis en place sur d’autres site. Ceci pour vous permettre d’avoir une meilleure vision d’ensemble des capacités de cet outil. Le forum étant à votre disposition pour toute demande d’aide, de conseils ou si vous constatez la moindre erreur.


2 contribution(s)

Par Christy le 24/10/2011 11:04:31 :

Merci,
Pour une meilleure lisibilité des différents tags ajoutés, ce serait bien plus facile pour le lecteur que la référence au n° de ligne
de la page soit clairement indiqué, ce serait plus facile pour le lecteur.
ex page ci-dessus :

1<atm-search-limit search="docsresult" value="10" />


2.<atm-search-page search="docsresult" value="{request:int:page}" />

Ligne : 18 et 31.

En lisant ceci je pose la question peut-être bête... mais !
le code qui est indiqué avc les tags :
On doit l'ajouter sur chaque page à travers l'administration d'automne ou en externe avec le utilitaires de codage (notepad,dreamweaver..)



Par Frank le 25/10/2011 11:02:38 :

Concernant le code indiqué, il est en général destiné à être employé dans un modèle de rangée ou directement dans un modèle de page.

Haut