Les crayons

Un plugin pour une édition directe sur le site public

Ce plugin permet d’éditer les contenus sur les pages publiques du site, sans passer par l’espace privé de SPIP.

Le paramétrage côté squelettes est des plus simples : il repose sur la classe #EDIT{...} adjointe aux éléments qu’on veut rendre modifiables.

Résumé

Après l’activation du plugin, les contenus peuvent être directement édités « en place » sur les pages publiques du site, par les personnes autorisées.

Cela demande de préparer vos squelettes pour les rendre compatibles avec ce plugin (à noter : c’est le cas de la plupart des squelettes distribués sur SPIP-Contrib). Le principe est simple : un bloc est éditable s’il contient la classe crayon objet-champ-id. Une balise #EDIT{} facilite encore l’écriture. En fait, pour permettre d’éditer le titre d’un article, il suffit de remplacer dans le squelette de la page article.html, la ligne (par exemple) :

<h1>#TITRE</h1>

par :

<h1 class="crayon article-titre-#ID_ARTICLE">#TITRE</h1>

ou encore, plus simplement :

<h1 class="#EDIT{titre}">#TITRE</h1>

Autre exemple, pour rendre « crayonnable » le texte d’un article, transformer :

[<div class="texte">(#TEXTE|image_reduire{520,0})</div>]

en :

[<div class="#EDIT{texte} texte">(#TEXTE|image_reduire{520,0})</div>]

Les pages concernées doivent obligatoirement comporter une balise </head>, écrit précisément de cette façon (lettres minuscules).

Fonctionnement

Fabrication de la page côté serveur

Lors du chargement d’une page, le plugin agit dans le pipeline affichage_final.

Il vérifie alors :

  • si l’utilisateur est identifié
  • si la page contient au moins une chaîne de caractères “crayon xxxx­-yyyy-nn”,
  • et si l’utilisateur possède des droits sur au moins un des éléments ainsi marqués

Le cas échéant, il insère dans le <head> de la page le script externe crayons.js ainsi que des données de configuration ; le script s’exécute à la fin du chargement de la page, et vérifie à intervalles réguliers si de nouveaux crayons sont disponibles, de façon à les activer en cas de besoin.


Chargement par le navigateur

Lorsque la page finit de se charger (et si le visiteur a des droits d’édition sur les crayons présents dans la page), le script crayons.js sélectionne tous les éléments possédant la classe crayon type­-champ-id, et si ils sont autorisés pour l’utilisateur inscrit, leur adjoint une image clicable (un crayon) et leur ajoute la classe crayon-autorise pour indiquer qu’ils sont « éditables ».

Un clic sur cette image, mais aussi un double-clic sur l’élément lui-même, provoquent l’activation du formulaire d’édition.


Activation du crayon

Un click sur le « crayon » (ou un double-clic sur l’élément) déclenche une requête vers le serveur, qui renvoie le formulaire de modification qui va « remplacer » l’élément affiché.

La requête spécifie au serveur le « type », le « champ » et l’« id » pour lesquels le formulaire est demandé.

Après vérification de l’existence des données et des droits sur celles-ci, le serveur renvoie le formulaire (sous forme de données javascript, au format JSON). Le type et les dimensions du champs sont déterminés d’après sa nature et la place réservée à l’élément. Il contient le source brut du texte, comme lorsque on édite depuis l’espace privé ; la police, la taille et la couleur des caractères sont préservées.

crayon.js associe ce formulaire à l’élément puis "cache" ce dernier.

L’utilisateur peut maintenant modifier les données.

Attention : l’affichage final ne peut être réalisé que par le serveur, un click en dehors de la zone d’entrée après des modifications affichera à nouveau le contenu originel.
Dans ce cas, une roue dentée vous signale que vous avez introduit une modification. Click sur le bouton ou double-click sur l’élément vous y ramène, elles ne sont pas perdues.
Si vous abandonnez cependant la page, un dernier rappel vous propose de sauvegarder.


Sauvegarde

Le formulaire possède une série de boutons/touches associées :

  • OK (ainsi que la touche Entrée [1]) permet de sauvegarder,
  • Annuler (ainsi que la touche Escape) abandonne toute mise à jour,
  • Un clic en dehors des zones de saisie cache ces zones et revient à l’affichage initial.

Il contient aussi des identificateurs et des clés associés aux données.

Le formulaire est soumis en POST par ajaxForm donc asynchrone. Sur réception, le serveur :

  • analyse les données soumises, leur cohérence et leur actualité (afin d’annuler l’envoi si les données ont été entre-temps modifiées par ailleurs).
  • vérifie une nouvelle fois les droits d’édition.
  • appelle les procédures internes de SPIP pour mettre à jour les données.
  • renvoie une vue des données modifiées, et déclenche les comportements javascript précisés par la fonction onAjaxLoad de SPIP.

Le système alimente notamment l’historique des modifications, de la même façon que l’espace privé.

Configuration

Le plugin propose plusieurs options, activables via le plugin CFG ; notamment :
-  un message si on confirme OK mais que rien n’est changé ;
-  une alerte permettant de sauvegarder les modifications si on abandonne la page alors qu’un texte est en cours d’édition ;
-  l’activation de la barre typographique ;
-  des couleurs permettant de mieux repérer les zones modifiables.

À noter : si le plugin est absent ou désactivé, la balise #EDIT{...} renvoie une chaîne vide ; cela permet donc de « crayonner » des squelettes même si l’on décide finalement de ne pas utiliser le plugin

Utilisation étendue

Toutes les tables standard de SPIP (articles, brèves, rubriques, etc.) sont gérées, y compris les forums et les signatures de pétition (mais, pour ces deux dernières, il faut utiliser le plugin Autorité pour permettre des modifications) ; pour chacune de ces tables, tous les champs de type « ligne » (titre, soustitre etc), ou « texte » (texte, chapo, descriptif...) sont crayonnables.

On peut également éditer les logos avec le crayon #EDIT{logo} ; un réglage permet de redimensionner ces logos à la volée lors de l’upload.

Les documents sont modifiables avec le crayon #EDIT{fichier} : le nouveau document vient remplacer l’ancien et sa taille, hauteur et largeur sont mises à jour. (NB : pas encore compatible documents distants).

Enfin, à partir de spip 2, on peut éditer les champs extra.

À noter :

  • Les crayons fonctionnent avec n’importe quelle table — à condition que cette table possède une clé primaire (numérique) qui s’appelle id_xxx, où le nom de la table est spip_xxxs.
  • pour la table spip_meta qui ne propose pas ce type d’index numérique, il faut utiliser la balise #EDIT d’une manière un peu différente en préfixant le champs à éditer par meta-, par exemple [2] :
    #EDIT{meta-descriptif_site}
    
  • pour éditer une valeur de configuration de plugin, on utilise la même syntaxe en ajoutant « meta » ; Par exemple pour éditer un champs de configuration adresse pour un plugin dont le préfixe est croque :
    [<div class="inner #EDIT{meta-croque/adresse}">(#CONFIG{croque/adresse})</div>]
    
  • Si un texte « crayonnable » est un champ MySQL MEDIUMTEXT ou plus long, les crayons affichent un TEXTAREA, et sinon, un INPUT.
  • Seuls les admins complets peuvent ainsi crayonner des textes provenant d’une table non-SPIP.

Editions simultanées de plusieurs champs

L’obtention du formulaire d’édition (« contrôleurs ») ainsi que la vue obtenue en retour sont surchargeables, par de simples squelettes (voir les exemples dans les répertoires controleurs/ et vues/ du plugin).

Ces formulaires peuvent travailler en parallèle sur plusieurs champs d’un enregistrement (article), voire plusieurs enregistrements d’une même table ou de tables différentes [3] : il y a là de quoi faire des interfaces d’édition spécialisées et très efficaces.

Comme toujours, contributrices et contributeurs sont bienvenus !

Notes

[1Ainsi que, sur Mac, la touche ctrl-S, et sur PC les touches alt-S ou F8, ou encore la combinaison MAJ-entrée.

[2Ceci est valable depuis la version 1.6.1 du plugin. Pour les versions précédentes la syntaxe est différente. Il faut insérer manuellement la class dans le code suivant la syntaxe meta-valeur-XXX où XXX représente le nom de la propriété à modifier. Par exemple pour modifier le nom du site (propriété : nom_site) on pourrait faire :

<h1 class="crayon meta-valeur-nom_site">#NOM_SITE_SPIP</h1>

[3Par exemple pour ouvrir en édition l’ensemble des champs descriptifs d’une adresse postale.

Debug : Les crayons ont un mode de débug activable en mettant dans mes_options.php la ligne suivante :

define('_DEBUG_CRAYONS', true);

Ce code ralentit un peu le fonctionnement, puisque le script est rechargé à chaque fois, mais facilite le repérage de bugs et le développement de nouvelles fonctionnalités.

Voir aussi : Doc complémentaire

Discussion

303 discussions

  • 1

    Je suis fan absolu. J’ose même pas croire que j’ai pu m’en passer pendant 5 ans.

    • T’es bien gentil ... en plus, tu sais pas tout, il y a encore plein de secrets dans crayons.

      Quand t’imagines qu’il y a cinq ans on pouvait faire pareil, mais pas aussi fluide
      pour les codeurs et donc pour les utilisateurs.

      Cinq ans ...

    Répondre à ce message

  • 1

    Extraordinaire ce plugin !
    Par contre, petit retour sur une boucle qui contient un texte de remplacement via le filtre sinon.

    (#TEXTE| ?#TEXTE," pas encore d’actions de suivi !")

    Dans ce cas, si je saisie du texte, pas de problèmes, il s’affiche.
    Mais... si je supprime complètement le texte saisi, le message affiché au cas où il n’y a rien dans #TEXTE ne réapparait pas...
    C’est pas très grave dans le sens où après un rechargement de la page, tout rentre dans l’ordre. Mais ce serait mieux ;-)

    • Comme Indiqué ci-dessous , crayons ignore ce qu’il y a dans ton squelette et ne passe qu’un filtrage basique, par contre, tu peux fabriquer toi-même ta propre vue et y insérer ton fragment de squelette correspondant.

    Répondre à ce message

  • Extraordinaire ce plugin !
    Par contre, petit retour sur une boucle qui contient un texte de remplacement via le filtre sinon.

    <div class="#EDIT{texte}">(#TEXTE|?{#TEXTE,"<span class='important'> pas encore d'actions de suivi !</span>"})</div>

    Dans ce cas, si je saisie du texte, pas de problèmes, il s’affiche.
    Mais... si je supprime complètement le texte saisi, le message affiché au cas où il n’y a rien dans #TEXTE ne réapparait pas...
    C’est pas très grave dans le sens où après un rechargement de la page, tout rentre dans l’ordre. Mais ce serait mieux ;-)

    Répondre à ce message

  • 6

    Ayant mis le plugin en service :

    1) L’enthousiasme général.

    2) Lorsqu’on édite un (#TITRE et clique sur OK, le titre apparaît sur la page avec le numéro. Ce n’est qu’un phénomène passager, mais cela a suffi pour dérouter quelques uns.

    3) Sur les pages publiques, un admin restreint a reçu l’erreur :
    Fatal error : Call to undefined function direction_css() in /usr/home/web/taizefr/www/plugins/crayons/tetecrayons.php on line 57

    -  après avoir vider son cache et détruit ses cookies l’erreur est partie.

    Paolo

    • 1) Merci pour les retours d’expérience

      2) Oui, Crayons ne passe que rudimentairement les filtres : propre pour ’chapo’, ’texte’, ’descriptif’ et ’ps’, et typo pour les autres champs, donc il peut y avoir de petites différence sur simple validation. On peut constater le même effet notamment avec les réductions d’images. Il faut un rechargement de la page pour obtenir le « vrai » filtrage du squelettes. Il ne serait malheureusement pas facile et de toute façon très coûteux de récupérer ce vrai filtre dans les squelettes ...

      3) Correct, c’est corrigé en 9395 , merci de l’avoir signalé.

    • Ok, merci. Je vais mettre le plugin à jour.

      Suggestion : comme |supprimer_numero n’est d’habitude utilisé que pour les champs TITRES, mais que là l’utilisation est très fréquente, et voir le numéro apparaître peut déconcerter les auteurs, peut-être appliquer |supprimer_numero systématiquement (sans lire le squelette) juste sur les champs TITRE ?

    • Comme je le disais, il serait très difficile de récupérer les filtres spécifiés dans le squelette, mais ...

      Comme indiqué dans ecrire/inc_version.php, il est possible en 1.9 de spécifier des filtres globalement par « champ » qui seront systématiquement passés sur les éléments. Par exemple, si tu veux que les numéros dans les titres soit toujours supprimés, mettre dans config/mes_options.php :

      $table_des_traitements['TITRE'][]= 'typo(supprimer_numero(%s))';

      Je pense que c’est d’ailleurs conseillé si tu veux éviter d’avoir à rajouter le filtre pour chaque utilisation de #TITRE (dans les pages, dans les cartouches de droite, etc.)

      Ça, je crois qu’on pourrait le « récupérer » facilement au réaffichage après validation, ça permettrait de faire du un peu plus sur mesure ...

      J’en discute avec Fil et on te tient au courant.

    • Comme indiqué dans ecrire/inc_version.php ...

      Il y a beaucoup plus dans ce fichier que je ne pensais. Merci !

      C’est très commode. Partout où il y a un titre j’ai un |supprimer_numero — et j’imagine qu’il en va de même pour plein de monde.

    • Oui, à tel point qu on envisage d en faire un standard dans les prochaines versions de spip (apres la 1.9.2)

    • Pour continuer cette intéressante discussion, une possibilité que j’avais oublié d’indiquer.

      Crayons permet aussi à l’implémenteur de spécifier des « controleurs » pour la saisie et des « vues » pour le ré-affichage après validation qui lui sont propres. On en trouve des exemples dans les sous-répertoires vues/ et controleurs/ distribués avec le paquet.

      Par exemple, pour ce cas du titre, on peut aussi créer une vue spécifique grâce à un fichier squelettes/vues/article_titre.html contenant :

      [(#REM)
      	Vue pour le crayon 'article_titre'
      ]
      #CACHE{0}
      <BOUCLE_a(ARTICLES){id_article}{statut==.}>
      [(#TITRE|supprimer_numero)]
      </BOUCLE_a>

      Dans ce cas, Crayons utilisera ce fragment de squelette pour réafficher le titre.

      Ça n’est pas nécessaire dans ce cas comme indiqué ci-dessous, c’est juste à titre d’exemple. Mais ce peut être bien utile lorsque on a des choses « speciales » dans son squelette.

      On peut même spécifier une vue générale pour tous les titres, aussi bien article que rubrique par exemple, en nommant cette vue squelettes/vues/titre.html . Bien sûr, ils faut alors plusieurs boucles alternatives selon le type concerné.

      Ces aspects de customisation, pour les controleurs aussi, sont en cours de documentation, je n’ai malheureusement guère eu de temps depuis un mois pour terminer cet article.

    Répondre à ce message

  • 4

    Bonsoir,

    C’est impressionant !

    Je ne sais pas si vous avez déjà rencontré le problème suivant. J’essaie avec cette ligne dans le squelette article :

    <h1 dir="#_lang0:LANG_DIR" class="#EDIT{titre} titre-texte">[(#_art0:TITRE|supprimer_numero)]</h1>

    Le préfixe #_art0 est nécessaire car cette balise de l’article est à l’intérieur d’une boucle rubriques (la boucle articles se trouve à l’extérieur de cette boucle rubriques). Et lorsque je clique sur le crayon, c’est le titre de la rubrique qui se présente pour être edité, non pas le titre de l’article.

    Paolo

    • Paolo tu es toujours notre testeur dans les recoins avancés :)

      Mais as-tu essayé #_art0:EDIT{titre} ? Il paraît logique de demander l’éditeur correspondant à ce qu’on affiche.

    • En essayant ce que tu proposes, c’est déjà mieux que les autres variantes que j’avais essayées. Avec #_art0:EDIT{titre} je reçois le message d’erreur :
      « rubrique 4378 titre : Pas de valeur »

      C’est déjà pas mal, parce que il a attrapé le id_article (4378), mais quelque part il croit toujours qu’il est nécessaire de chercher une rubrique.

      Paolo

    • Ah ! En effet la recherche du type de boucle était un peu trop basique... C’est corrigé en [9366]

      Merci !

    • C’est parfait : le titre de l’article est maintenant correctement reconnu, même à l’intérieur d’une boucle rubriques ou mots.

      merci, Paolo

    Répondre à ce message

  • 3

    J’aimerais savoir comment faire pour modifier crayon de manière à pouvoir l’utiliser pour modifier le contenu de champs de tables perso créés dans spip. des tables spip_nomdetable nouvelles.

    Est ce possible ?

    • Je précise ma question, j’ai l’intention de créer des tables pour gérer d’autres données non spip mais en les déclarant dans une fonction qui permette à spip de les exploiter.

      J’aimerais ensuite pouvoir utiliser « crayon » pour modifier le contenu de ces tables depuis l’espace public.

      Et j’aimerais savoir dans quelle partie du plugin « crayon » il faut ajouter des informations sur les tables que l’on veut modifier.

      Merci

    • En théorie, c’est possible.

      Il y a deux interfaces à fournir autoriser(’modifier’, $type,...) $type étant le nom de ta table sans « spip_ » et revision_xxx(...) xxx étant ce $type.

      C’est quasi encore non expérimenté, mais c’est prévu. Le plus rapide serait de venir en discuter sur et qu’on fasse bouger ça.

    • irc ://irc.freenode.net/spip je voulais dire ...

    Répondre à ce message

  • 1

    Un truc bête... J’ai téléchargé mon site en ligne à partir d’une version en local. Et le plugin crayons ne fonctionnait pas... C’était tout simplement mon squelette inc-head.html qui avait incomplètement été uploadé (manquait la ligne #INSERT_HEAD).

    • Dans sa version actuelle les crayons sont totalement autonomes, et en particulier sont indépendants de la balise #INSERT_HEAD ; ils embarquent même leur propre version de jQuery.

    Répondre à ce message

  • 5

    Nouveau petit souci : lorsque le plugin est activé les liens hypertexte ne fonctionnent plus sous Safari : il faut les ouvrir dans une nouvelle fenêtre ou un nouvel onglet (ils fonctionnent correctement sur Firefox...).

    • Là, je ne vais guère pouvoir aider directement, je ne possède pas cette technologie, il va falloir attendre le retour de Fil et son mac (sa machine, pas son souteneur) ...

      Néanmoins, pourrais-tu préciser de quels liens hypertextes tu parles ? Y a-t-il des messages d’erreur javascript ?

    • Je n’ai aucun message d’erreur particulier sous Safari (ou alors ils sont bien cachés), le navigateur se contente de rester inerte...

      Les liens hypertextes sont ceux composés en standard dans SPIP :
      -  externes de type : [Métadonnées->http://fr.wikipedia.org/wiki/Métadonnées]
      -  ou internes de type : [Bibliographie->rub6]

      Désolé, j’ai pas plus d’info...

      Bon, ça marche déjà sous Firefox et le double-clic active bien Crayons, ce qui est l’effet attendu ;-)

    • Ok, merci pour le complément d’information , en googlant un peu , je situe l’origine du problème.

      J’ai apporté une correction , révision 8303 ou le zip du train de 11H

      Confirmes si ça change quelque chose, s’il te plait.

    • OK, juste un petit moment pour me familiariser avec svn et je reviens vers toi asap.

      J’ai constaté d’autres petits défauts, comme une édition de la version « affichée » et non « source » lorsqu’on édite un article directement depuis la racine de SPIP (page d’accueil du site). Je continue à les mettre dans ce forum, ou j’ai vu qu’il y avait un espace bogues ?

      Joyeuses fêtes de fin d’année !

      Francis

    • Ça marche pas mieux :-(

    Répondre à ce message

  • 2

    Bonjour

    Je viens d’installer SPIP 1.9.2 beta 3 [8159], d’activer Crayons et de faire les modifications dans les en-têtes (insertion du #INSERT_HEAD dans le <head>).

    Les crayons apparaissent bien en face des zones modifiables, mais lorsque je clique dessus, j’ai une jolie roue qui tourne mais plus rien ne se passe. Firefox me donne un message d’erreur du type :

    Too much recursion (line 2389) :
    2389 return jQuery._ajax( type, url, data, ret, ifModified ); 

    Les résultats sont identiques si je suis à la racine du site ou non et cela donne la même chose sous Safari (sauf qu’il ne donne pas de message d’erreur ;->).

    Une petite indication ?

    Thanks

    • Cette erreur insique sans doute que tu as deux balises #INSERT_HEAD.

      Attention , cette balise est déjà dans la distribution 1.9.2 à l’intérieur du « sous-squelette » inc-head.html inclus par <INCLURE{fond=inc-head}> , donc il n’y a pas lieu de la rajouter dans ce cas.

      C’est seulement nécessaire losqu’on utilise un jeu de squelette propre , issu par exemple d’une version antérieure de spip.

    • Oh oui, ça marche maintenant, c’est beau !

      C’est carrément cool quand tout marche tout seul et qu’on n’a plus rien à faire ! :-D

      Thanks a lot

    Répondre à ce message

  • 2

    Merci beaucoup pour ce merveilleux plugin.
    J’ai activer le plugin mais j’obtiens cela :

    Fatal error : Call to undefined function interprete_argument_balise() in /home2/civ/public_html/spip1/plugins/crayons/tetecrayons.php on line 106

    Quelqu’un peut m’aider ?
    Merci

    • Attention, ce plugin ne fonctionne qu’en spip 1.9.2 svn , je crains que ce ne soit pas ton cas ou en tout cas, ta version est une vieille version antérieure au 4 octobre, date à laquelle cette fonction a été introduite.

      Il te faut upgrader , je pense.

    • Je comprends là :) Merci
      J’attendrai le plug officiel

    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