Dotclear mot de passe QUE sur le contenu d'un billet

billet-test-la-cigale-et-l-fourmi.jpg

L'image ci dessus explique tout, le désir c'est de protéger des billets par un simple mot de passe. Mais il faut que:

  • Le billet reste listé sur le blog
  • le titre le content exerp toussa idem
  • C'est juste le contenu du billet qu'on va remplacer par un formulaire mot de passe.

Ce n'est pas pour ce blog, mais pour le site du réseau d'établissement gériatriques. Ils ne souhaitent pas que les comptes rendus de réunion, qui sont mis en billets soient totalement publics. (rien de très confidentiel, au contraire, c'est simplement une crainte d'image négative)

Dotclear propose un système de mots de passes aux billets. Il a pour effet secondaire de faire que le billet n'est plus visible sur la page d'accueil. Il existe aussi un pluggin prvcat qui permet de de mettre un mot de passe à des catégories entières. Même effet secondaire.

Wordpress propose à peu près ce que je voudrai mais là c'est dotclear.

Voici un exemple sur le blog d'Emma: emma-mot-de-passe.jpg

Dans l'ordre, il faudra:

  • Différencier les billets protégés: avec le plugin mymeta
  • Adapter le template pour que par défaut il affiche le formulaire de mot de passe.
  • Un chouilla d'ajax pour remplacer ce formulaire par le contenu du billet suite à l'authentification.
  • Un plugin dotclear made by Gnieark qui sert à n'afficher que le contenu d'un billet (si mot de passe OK)

Différencier les billets à protéger par mot de passe.

Pour savoir quels billets protéger par mot de passe, j'ai choisi d'utiliser le pluggin Mymeta.

Apres avoir installé le pluggin, j'ajoute une meta de type case à cocher nommée "limited_access".

mymeta-case-cocher.jpgmymeta-nouveau.jpg

Dans l'interface de modification d'un billet ça se présente comme ça: Une case à cocher en dessous: meta-dotclear.jpg

Adapter le template

Lorsqu'un billet a l'attribut mymeta de type limited_access égal à '1', on affiche le résumé, puis une zone de mot de passe. les fichiers qui vont nous intéresser ce sont:

  • category.html
  • home.html
  • post.html
  • tags.html

(tous les fichiers qui affichent des billets en fait).

Tout se fait bien évidemment dans la boucle qui affiche les billets, généralement délimtée par <tpl:Entries> et </tpl:Entries>

Ne collez pas le code qui suit, c'est juste pour montrer comment on utilise Mymeta dans le template:

  1. <tpl:MyMetaIf type="limited_access" value="1">
  2. /* Inclure ici le code qui affichera la boite de mot de passe*/
  3. </tpl:MyMetaIf>
  4.  
  5. <tpl:MyMetaIf type="limited_access" defined="false">
  6. /* Inclure ici le code qui affichera le content d'un billet non protégé*/
  7. </tpl:MyMetaIf>

Exemple pour post.html

Ça se passe dans la partie <!\-\- # Entry with an excerpt \-\-> du fichier. Les identifiants de la div contenu et du champs de mot de passe ont été mis pour le javascript (chapitre qui suit).

  1. <!-- # Entry with an excerpt -->
  2. <tpl:EntryIf extended="1">
  3. <div class="post-excerpt">{{tpl:EntryExcerpt}}</div>
  4. </tpl:EntryIf>
  5.  
  6.  
  7. <div class="post-content" id="post-content{{tpl:EntryID}}">
  8. <tpl:MyMetaIf type="limited_access" value="1">
  9. <div class="formpassword">
  10. <h2>{{tpl:lang Password needed}}</h2>
  11. <p>{{tpl:lang You must give a password to access this area.}}</p>
  12. <p><label>{{tpl:lang Password:}} <input type="password" id="password_{{tpl:EntryID}}" value="" tabindex="1" /></label> <input type="submit" value="ok" onclick="deverouille('{{tpl:EntryID}}');";/></p>
  13. </div>
  14. </tpl:MyMetaIf>
  15.  
  16. <tpl:MyMetaIf type="limited_access" defined="false">
  17. {{tpl:EntryContent}}
  18. </tpl:MyMetaIf>
  19. </div>

Exemple pour les autres fichiers

Dans category.html, home.html, tags.html contrairement à post.html, s'il y a une description, on n'affiche pas le billet en entier juste sa description.

  1. <div class="post-content" id="post-content{{tpl:EntryID}}">
  2. <!-- # Entry with an excerpt -->
  3. <tpl:EntryIf extended="1">
  4. {{tpl:EntryExcerpt}}
  5. <!-- # acces limité; limited_access=1 (Mymeta) -->
  6. <tpl:MyMetaIf type="limited_access" value="1">
  7. <div class="formpassword">
  8. <h2>{{tpl:lang Password needed}}</h2>
  9. <p>{{tpl:lang You must give a password to access this area.}}</p>
  10. <p><label>{{tpl:lang Password:}} <input type="password" id="password_{{tpl:EntryID}}" value="" tabindex="1" /></label> <input type="submit" value="ok" onclick="deverouille('{{tpl:EntryID}}');";/></p>
  11. </div>
  12. </tpl:MyMetaIf>
  13.  
  14. <!-- # acces llibre; limited_access=0 ou est null (Mymeta) -->
  15. <tpl:MyMetaIf type="limited_access" defined="false">
  16. <p class="read-it"><a href="{{tpl:EntryURL}}" title="{{tpl:lang Continue reading}} {{tpl:EntryTitle encode_html="1"}}">{{tpl:lang Continue reading}}</a>...</p>
  17. </tpl:MyMetaIf>
  18. </tpl:EntryIf>
  19.  
  20. <!-- # Entry without excerpt -->
  21. <tpl:EntryIf extended="0">
  22. <!-- # acces limité; limited_access=1 (Mymeta) -->
  23. <tpl:MyMetaIf type="limited_access" value="1">
  24. <div class="formpassword">
  25. <h2>{{tpl:lang Password needed}}</h2>
  26. <p>{{tpl:lang You must give a password to access this area.}}</p>
  27. <p><label>{{tpl:lang Password:}} <input type="password" id="password_{{tpl:EntryID}}" value="" tabindex="1" /></label> <input type="submit" value="ok" onclick="deverouille('{{tpl:EntryID}}');";/></p>
  28. </div>
  29. </tpl:MyMetaIf>
  30. <!-- # acces llibre; limited_access=0 ou est null (Mymeta) -->
  31. <tpl:MyMetaIf type="limited_access" defined="false">
  32. <div class="post-contenu">{{tpl:EntryContent}}</div>
  33. </tpl:MyMetaIf>
  34. </tpl:EntryIf>
  35. </div>

Fichiers de template des flux

rss2.xml

La modification se fait entre les balises <description>et </description>

  1. <description>
  2. <tpl:MyMetaIf type="limited_access" value="1">
  3. &lt;p&gt;Le contenu de ce billet est protégé par mot de passe. Rendez-vous sur le site pour le lire.&lt;/p&gt;
  4. </tpl:MyMetaIf>
  5. <tpl:MyMetaIf type="limited_access" defined="false">
  6. {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}}
  7. {{tpl:EntryContent absolute_urls="1" encode_xml="1"}}
  8. </tpl:MyMetaIf>
  9. </description>

atom.xml

La modification se fait entre les balises <content type="html">et </content>

  1. <content type="html">
  2. <tpl:MyMetaIf type="limited_access" value="1">
  3. &lt;p&gt;Le contenu de ce billet est protégé par mot de passe. Rendez-vous sur le site pour le lire.&lt;/p&gt;
  4. </tpl:MyMetaIf>
  5. <tpl:MyMetaIf type="limited_access" defined="false">
  6. {{tpl:EntryExcerpt absolute_urls="1" encode_xml="1"}}
  7. {{tpl:EntryContent absolute_urls="1" encode_xml="1"}}
  8. </tpl:MyMetaIf>
  9. </content>

On est ok pour la partie html du template. En adaptant un peu le CSS, l'aperçu est en en-tête de ce billet.

Le code javascript qui affichera le "content" du billet protégé

Une fonction ajax qui appelle un script et rafraichit la div qui contient le contenu du billet.

A la source du dossier de template, je créée un fichier qui s'appelle password.js

Il contient:

  1. function Ajx() {
  2. var request = false;
  3. try {request = new ActiveXObject('Msxml2.XMLHTTP');} catch (err2){ try {request = new ActiveXObject('Microsoft.XMLHTTP');} catch (err3) {try {request = new XMLHttpRequest();} catch (err1) {request = false;}}}
  4. return request;
  5. }
  6.  
  7. function deverouille(postid){
  8. var xhr = Ajx();
  9. xhr.onreadystatechange = function(){
  10. if(xhr.readyState == 4){
  11. if(xhr.status == 200){
  12. if (xhr.responseText=="fail")
  13. {
  14. document.getElementById('post-content' + postid).innerHTML =document.getElementById('post-content' + postid).innerHTML + '<p>Erreur de mot de passe</p>';
  15. }else{
  16. document.getElementById('post-content' + postid).innerHTML =xhr.responseText;
  17. }
  18. }else{
  19. document.getElementById('post-content' + postid).innerHTML = "<font color=\"#FF0000\">Error code " + xhr.status + "</font>";
  20. }
  21. }
  22. };
  23. xhr.open("POST", './index.php?justunpost/' + postid, true);
  24. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  25. xhr.send("pass=" + document.getElementById('password_' + postid).value);
  26. }

Dans le fichier de template _head.html, on ajoute le lien vers le nouveau script, juste apres </style>:

  1. <script type="text/javascript" src="{{tpl:BlogThemeURL}}/password.js"></script>

Le script fait la requete suivante pour réupérer le contenu (et uniquement le contenu, pas les header ni rien) :index.php?justunpost/' + postid où posid est l'identifiant du billet. On va donc créer un plugin dotclear qui retourne juste le contenu du billet, à condition que le mot de passe soit vérifié.

Le plugin justunpost

Mon premier plugin dotclear :D. Il est tout simple, mais comme je ne sais pas faire les plugins, ça m'a pris pas mal de temps. Il sert à ce que l'URL http://www.domaine.com/index.php?justunpost/21 retourne le contenu du billet 21, à condition que la variable passée en POST ($_POST['pass']) corresponde au mot de passe.

Installez le tout simplement depuis le menu des extensions de dotclear. Télécharger justunpost.zip

Il doit s'afficher dans la liste des extensions du panneau d'administration de dotclear. Allez y, pour définir un mot de passe.

C'est le mot de passe qu'il faudra rentrer au niveau du billet dans la partie publique du blog pour lire son contenu.

Conclusion

Normalement ça marche, je vais pouvoir lire la suite de l'histoire de la cigale et la fourmi.

Limite de la méthode

Comme le signale @PhilippeVay Les ressources liées (photos etc....) ne sont pas protégées, on peut toujours y accéder directement par leur URL. Il n'y en aura pas sur le site en question, c'est pour ça que je le fais de cette façon.

Ps le site en question est là

Commentaires

1. Le dimanche, novembre 7 2010, 21:59 par julien

Article très intéressant, merci beaucoup.

J'ai le sentiment qu'il manque quelque chose : les flux RSS et Atom n'ayant pas été modifiés, j'ai l'impression que le contenu du billet doit toujours s'y trouver au complet... Il faudrait dans ce cas-là proposer un lien pour accéder à la page du billet en lieu et place du contenu (puisqu'il n'est alors pas possible d'utiliser Ajax pour remplacer au vol le contenu).

2. Le dimanche, novembre 7 2010, 22:20 par gnieark

En effet julien :oups:
Les flux rss et atom peuvent aussi se gérer au niveau du template. j'ai modifié le billet.
Votre idée de remplacer le contenu par un message genre "billet verrouillé veuillez vous rendre à l'adresse..... pour le lire" me parait être la bonne, mais là dans l'immédiat avec les endode xml, je n'ai pas trouvé comment mettre un lien dans le flux, juste un message "Rendez-vous sur le site pour le lire".

3. Le mardi, novembre 9 2010, 07:25 par julien

Il y a encore une petite erreur dans les deux flux de syndication : il y a un "&lt;/a&gt;" qui traîne alors que la balise "a" n'a pas été ouverte...

4. Le mardi, novembre 9 2010, 11:51 par gnieark

corrigé. merci pour ce retour,

julien, histoire de découvrir un peu mieux l'API dotclear, je tenterai bien un plugin complet de ce billet.

je me demande si un plugin pourrait modifier le comportement de $core->blog->getPosts afin de modifier le post_content_xhtml à ce niveau. Une idée là dessus?

5. Le vendredi, décembre 24 2010, 15:41 par Fab

Hello ! Merci pour ce très bon tuto et tout ce dur travail réalisé.

Juste une question : dans l'admin de justunpost, le mot de passe ne semble pas mémorisé. Résultat : le mot de passe accepté peut être vide, on accède au billet.

D'où vient mon erreur ?

Merci pour votre réponse.

6. Le vendredi, décembre 24 2010, 16:36 par gnieark

ah oui.

Lors de la modification du mot de passe il ne s'affiche pas en effet. cliquez sur le lien justeunpost dans le menu des extensions, il s'affiche :D. C'est pas bloquant, mais je corrige ce petit défaut du pluggin et vous préviens par mail des que c'est fait.

7. Le vendredi, décembre 24 2010, 16:58 par gnieark

J'ai corrigé, la petite erreur sur le pluggin. Mais on peut en effet mettre un mot de passe vide.

http://blog-du-grouik.tinad.fr/publ...

Page top