Crayons : Contrôleurs et Vues

Cet article est en cours de rédaction (donc incomplet), merci si vous avez :
-  des corrections,
-  des compléments,
-  des exemples (simples si possible),
-  des captures d’écran ou videos de démo,
-  une traduction
à proposer, n’hésitez pas.

Les contrôleurs sont les fragments de formulaires chargés par Crayons pour éditer les contenus.
Les vues sont les fragments de HTML renvoyés par le serveur après modification.

Fragments HTML utilisés par Crayons

Dans son fonctionnement, crayons demande au serveur des fragments d’HTML pour changer dynamiquement l’affichage de morceaux de la page :
-  au clic sur le crayon, ou au double-clic sur le contenu, il requiert du serveur le formulaire qui permettra d’éditer l’élément. Ce formulaire comporte des contrôles techniques et inclut un fragment pour les données elles-même le contrôleur.
-  lorsque l’on soumet la modification, le serveur renvoie le fragment correspondant à l’affichage de l’élément. C’est la vue.

Par défaut, pour les champs « simples » (une colonne d’une table), le noyau de crayons les fabrique en interne. Il est aussi possible de fournir des contrôleurs et vues propres, notamment pour des champs multiples. C’est possible par html similaire aux modèles, par code php, ou combinaison des deux.

Il est important de noter que la vue n’est pas un extrait du squelette de départ [1], mais un morceau re-fabriqué en dehors de l’environnement complet de celui-ci et que donc, il peut exister des différences minimes dans certains cas relativement rares.

Fonctionnement par défaut

La classe #EDIT{machin} produit l’expression « crayon objet-machin-id ». Typiquement, comme dans la distribution de SPIP, objet est une table, machin une colonne et id le numéro d’enregistrement dans la table. Cette expression est à installer dans la class d’un élément qui entoure ce qu’on veut éditer.

Par défaut, crayons établit un champ simple pour ce machin, un <input> ou <textarea> selon sa nature. Bien sûr, toujours accompagné des boutons de validation.

Contrôleurs

Lorsque l’on clique sur le crayons ou que l’on double-clique l’élément, le javascript transmet dans son appel ajax à SPIP l’intégralité de la classe de l’élément.

Le contrôleur en déduit l’objet concerné, ses « objet », « machin » et « id ». Grâce à ces données, il peut calculer et envoyer le formulaire de modification de l’élément.

Crayons renvoie un formulaire soit défaut, soit customisé si il trouve, par exemple dans les squelettes ou chez un autre plugin, un fichier nommé controleurs/objet_machin.html ou plus généralement controleurs/machin.html (pour tous les objets si pas de objet-machin.html).

Vues

Lorsque l’on valide le formulaire, le serveur vérifie la véracité, l’intégralité, la non-concurrence (édition simultanée par plusieurs rédacteurs) et les droits sur les données transmises, et modifie en conséquence la base de données. Ensuite, il renvoie la vue du nouvel objet.

De même que pour le contrôleur, c’est une vue défaut avec un minimum de filtres selon le « machin », sauf si l’on trouve un vues/objet_machin.html ou plus généralement vues/machin.html.

Compléments de documentation et exemples

Trouvez et déposez des compléments de documentation sur les crayons et leurs contrôleurs et vues, et des exemples, sur le wiki

Notes

[1quoiqu’il soit possible de fabriquer le squelette de départ par include de la vue

Discussion

9 discussions

  • Bonjour,
    je viens de mettre à jour le wiki avec un exemple d’utilisation du datepicker pour un champ date

    Répondre à ce message

  • 2

     :-(

    Les crayons ne prennent pas en compte les « surnoms » pour les nouveaux objets créés dans des plugins... Par exemple, j’utilise un objet appelé « entidad », soit au pluriel « entidades » (en espagnol). Le contrôleur et la vue doivent s’appeler :

    • controleurs/entidade.html
    • vues/entidade.html
      pour que ca marche, et dans ces fichiers, je dois mettre :
      <BOUCLE_a(ENTIDADES){id_entidad=#ENV{id_entidade}}{tous}>

      pour avoir un resultat dans ma boucle... C’est a dire que les crayons retirent simplement un « s » a la table pour récupérer le nom de l’objet.

    J’imagine qu’on pourrait faire le test avec « hibou/hiboux » et on obtiendrait le même résultat problématique...

    (j’utilise SPIP 3.0.0-alpha et Crayons 1.12.1)

    • C’est décrit dans http://contrib.spip.net/Crayons-controleurs-et-vues-doc-complementaire :

      Nom servant d’index dans l’environnement reçu par un contrôleur

      Le contrôleur reçoit un environnement avec la valeur de l’index de l’enregistrement édité, affecté à un nom qui est bien l’index de la table si la table suit les conventions de nommage élémentaires de SPIP : c’est à dire lorsque le nom du champ index est de la forme ’id_table’ et la table s’appelle ’TABLE’ ou ’TABLES’.

      Si donc la table est « PLOUF’, l’index reçu a pour nom ’id_plouf’ même si le vrai champ index de la table PLOUF est »mon_idploc". Il faudra alors dans ce cas faire le lien dans la boucle avec :

    • bonjour

      impossible de faire fonctionner cet exemple en SPIP3

      les #ENV{name_xxx) ne sont pas passés dans le controleur

      J’ai essayé de les reconstituer en écrivant

      name="content_#ENV{key)_xxx"

      mais à ma grande surprise cela ne fonctionne pas non plus.... si quelqu’un a une piste merci !

    Répondre à ce message

  • J’ai voulu utiliser les saisies pour un controleur perso. Dans mon cas : des radio-boutons.

    Le code :

    #CACHE{0}
    <ul>
        <li class="fieldset" style="#ENV{largeur}px;#ENV{style}">
            <ul>
                <li class="editer_monchamp">
                    <input type="hidden" name="#ENV{name_monchamp}"/>
                    [(#SAISIE{radio, #ENV{name_monchamp},
                        label=<:monplugin:monchamp:>,
                        valeur_forcee=#GET{monchamp},
                        datas=#ARRAY{
                            0, <:monplugin:label_monchamp_false:>,
                            1, <:monplugin:label_monchamp_true:>}
                    })]
                </li>
            </ul>
        </li>
    </ul>

    A noter :

    • Sans inclure le champ caché : <input type="hidden" name="#ENV{name_monchamp}"/>, la saisie est vide. Il faut rajouter absolument cette ligne.
    • il a fallu aussi passer la valeur du champ, avec valeur_forcee, elle ne passe pas toute seule.

    Bon, a vérifier dans d’autres cas, mais il semblerait qu’il est necessaire de créer un champ caché pour utiliser les saisies dans les controleurs des crayons.

    Répondre à ce message

  • 6

    Exemple d’utilisation avec champ extra.

    Cela doit être possible de le faire plus simplement au niveau de mon contrôleur car je n’utilise pas les valeurs stockées dans la table meta, et du coup je suis obligé de répéter au niveau de mon « select » toutes les « options », mais en tout cas cela fonctionne, si quelqu’un sait faire cela plus propre, je suis preneur :-)

    j’ai créer un champ extra (avec extras2) lié à un article, ce champ est en type : menu-enum, pour cet l’exemple je l’appelle « tests ». pour l’exemple je suis parti sur les mois de l’année mais cela aurait pu être, des fruits, des qualifications, ou tout autre choses ...

    Je crée donc dans mon répertoire squelette un répertoire « controleurs » et un répertoire « vues ».

    dans mon répertoire « controleurs » je crée un fichier « tests.html » avec ce code :

    [(#REM)
    
    	Controleur pour le crayon 'tests', lié à un article
    
    ]
    #CACHE{0}
    
    <BOUCLE_a(ARTICLES){id_article}{statut==.}>
    #SET{tests,#tests}
    </BOUCLE_a>
    
    
    <BOUCLE_a(ARTICLES){id_article}{statut==.}>
    #SET{tests,#TESTS}
    </BOUCLE_a>
    
    
    <select class="crayon-active" name="#ENV{name_tests}" >
    <BOUCLE_r(ARTICLES){id_article} {tests}>
    <option value="1" [(#GET{tests}|=={1}|?{selected})]>Janvier</option>
    <option value="2" [(#GET{tests}|=={2}|?{selected})]>Février</option>
    <option value="3" [(#GET{tests}|=={3}|?{selected})]>Mars</option>
    <option value="4" [(#GET{tests}|=={4}|?{selected})]>Avril</option>
    <option value="5" [(#GET{tests}|=={5}|?{selected})]>Mai</option>
    <option value="6" [(#GET{tests}|=={6}|?{selected})]>Juin</option>
    <option value="7" [(#GET{tests}|=={7}|?{selected})]>Juillet</option>
    <option value="8" [(#GET{tests}|=={8}|?{selected})]>Août</option>
    <option value="9" [(#GET{tests}|=={9}|?{selected})]>Septembre</option>
    <option value="10" [(#GET{tests}|=={10}|?{selected})]>Octobre</option>
    <option value="11" [(#GET{tests}|=={11}|?{selected})]>Novembre</option>
    <option value="12" [(#GET{tests}|=={12}|?{selected})]>Décembre</option>
    </BOUCLE_r>
    </select>

    et dans mon répertoire « vues » je crée un fichier « tests.html » avec ce code :

    [(#REM)
    
    	Vue pour le crayon "tests"
    	Cf. controleurs/tests.html
    ]
    <BOUCLE_tests(ARTICLES) {id_article=#ENV*{id_article}} {#ENV*{tests}} {statut==.}>
    #LISTER_VALEURS{tests}
    </BOUCLE_tests>

    et dans mon squelette « article.html » j’utilise cette ligne :

    <div class="#EDIT{mois} mois">#LISTER_VALEURS{mois}</div>

    Si cela peut aider quelqu’un !!

    • On ne se relit jamais assez :-(

      il y a une erreur sur le dernier code

      voici le bon :

      <div class="#EDIT{tests} tests">#LISTER_VALEURS{tests}</div>
    • dans la boucle

      <BOUCLE_r(ARTICLES){id_article} {tests}>

      il faut mettre :

      <BOUCLE_r(ARTICLES){id_article} {par tests}>

      (Merci à Cyril Marion !)

    • Chez moi, cela n’a marché qu’en mettant les valeurs partout.
      C’est à dire qu’à la place de :

      <option value="1" [(#GET{tests}|=={1}|?{selected})]>Janvier</option>

      J’ai mis :

      <option value="Janvier" [(#GET{tests}|=={Janvier}|?{selected})]>Janvier</option>

      Par contre, je suis obligée de recharger la page pour que la modification s’affiche.

    • j’ai le même problème que toi. Je dois recharger la page. As-tu trouvé la solution ?
      Mais il est vrai que ce n’est pas très propre comme méthode, l’idéal serait de récupérer les données (stockées sous format JSON je crois) du champs extra !

    • Le problème venait d’un critère d’une boucle AUTEURS dans le fichier vue... Une boucle sur un auteur qui n’a pas écrit d’article ne renvoie rien, il faut lui mettre le critère tout pour qu’elle renvoie qqchose.

    • Hourra, j’ai enfin trouvé !

      Après avoir mis des

      {tout}

      dans toutes mes boucles auteurs, j’ai supprimé le

       {#ENV*{tests}}

      de l’exemple, et ça marche !

    Répondre à ce message

  • moi aussi, « j’me réponds » ;-)

    pour que le select correspondant soit sélectionné à l’ouverture du crayon, il faut mettre dans la boucle qui « set » le « id » :
    #SET{id,#ID_TYPE_ACTION}

    et comme critère à la boucle :
    <BOUCLE_a(ACTIONS){id_action=#ID_ACTIONS}>

    Je pense que le #ID_xx doit prendre le nom de la table, et non le nom de la variable comme je faisais avant...

    Cyril

    Répondre à ce message

  • Hello,

    Petit exemple de réalisation sur une table non-spip.

    Objectif : dans une page servant à la mise au point d’une table, dans une colonne affichant un INT, je voulais dérouler avec les crayons une liste de noms en clair plutôt que d’ouvrir un bête input et de saisir l’entier correspondant à la main. A la place d’un nombre donc je voulais une valeur « en texte clair ».

    Réalisation : je me suis inspiré du contrôleur « id_parent » livré dans le répertoire « controleurs » des crayons, du fait qu’il présnetait une liste.

    Code :

    #CACHE{0}
    [(#REM)
    
    	Contrôleur pour le crayon 'id_type_action' , uniquement html
    
    ]
    
    <BOUCLE_a(ACTIONS){id_action}>
    #SET{id,#ID_TYPE_ACTION}
    </BOUCLE_a>
    
    <select  class="crayon-active" name="#ENV{name_id_type_action}" >
    
    	[(#REM) on récupère le texte "nom_type_action" correspondant à l'entier "id_action" dans une la table "types_actions" ]
    	<BOUCLE_ta(TYPES_ACTIONS){par id_type_action}>
    	<option value="#ID_TYPE_ACTION" [(#GET{id}|=={#ID_TYPE_ACTION}|?{selected})]>#NOM_TYPE_ACTION</option>
    	</BOUCLE_ta>
    </select>

    Important : la valeur de l’attribut « name » du select doit être de la forme #ENVname_nom_du_champ

    Pour l’instant je n’ai pas encore réussi à faire fonctionner le « selected »... mais j’ai bon espoir !

    Bonne utilisation,
    Cyril

    Répondre à ce message

  • 3

    J’ai l’impression qu’il y a un problème avec la boucle SITES et les contrôleurs.

    Dés que j’utilise un contrôleur avec la boucle SITES, je me retrouve avec juste les 2 boutons (rien ne s’affiche).

    Exemple sur le #STATUT d’une boucle SITES :
    Nom de mon fichier : statutsite.html

    <BOUCLE_g(SITES){id_syndic}{statut==.}>
    
    #SET{id,#STATUT}
    <select class="crayon-active" name="#ENV{name_statut}" style="width:#ENV{largeur}px;" >
    	<option value="publie"[(#GET{id}|=={publie}?{selected})]>publié</option>
    	<option value="prop"[(#GET{id}|=={prop}?{selected})]>proposé</option>
    	<option value="refuse"[(#GET{id}|=={refuse}?{selected})]>refusé</option>
    </select>
    
    </BOUCLE_g>

    Appel par :

      <div class="#EDIT{statutsite} mis_a_jour">#STATUT</div>

    Le même contrôleur adapté à la boucle SYNDIC_ARTICLES fonctionne parfaitement.
    Le problème se répète sur plusieurs contrôleurs (comme sur celui adapté de « syndic_article_hyperlien » par exemple).

    Si je n’utilise pas de contrôleur, aucun problème.
    J’ai une version à jour.

    Merci

    • J’ai oublié de préciser que je suis en 1.9.2d

    • En définitive, je me retrouve avec :

      L’obligation d’utiliser les contrôleurs et vues pour la boucle SYNDIC_ARTICLES

      L’obligation de ne pas utiliser les contrôleurs et vues pour la boucle SYNDIC

      Est-ce normal docteur ?

      Quelqu’un aurait-il déjà utiliser les crayons pour ces 2 boucles ?

    • Je me réponds :

      Pour la boucle SITES, il faut mettre comme critère de sélection {id_syndic=#ENV{id_site}}
      Du coup, les contrôleurs fonctionnent

      Voir le contrôleur « hyperlien », présent dans ce plugin, pour plus d’information.

      PS : Promis, j’arrête de me servir de ce forum comme bloc note :)

    Répondre à ce message

  • 2

    Une petite erreur dans le contrôleur statut :

    Un slash / en trop à la fin de la balise select.

    Maintenant la liste déroulante fonctionne mieux :)

    Répondre à ce message

  • Bonjour,
    je réalise mon premier controleur qui sert à modifier les mots-clefs d’un objet.

    Le formulaire dans controleurs/objet_machin.html est parfaitement chargé, le squelette s’éxécute, le formulaire est affiché avec les données de la base, magnifique.

    Mon problème est : comment renvoyer les données dans la base ? il semble que les zones du formulaire doivent s’appeler quelque chose comme #ENVname_machin ? Comment faire pour des données multiples (plusieurs mots-clefs pour 1 article ?)

    Merci des lumières (et je m’engage à compléter l’article dès que ca fonctionne, avec même lien url).

    Michel

    Répondre à ce message

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom