r1r2, un squelette simple dans un plugin simple - le tutoriel

Ceci est une « contribution pédagogique », qui montre par l’exemple comment développer une nouvelle fonctionnalité pour SPIP.

On cherche ici à faire un site simple, un site de présentation sans autre fonctionnalité, avec un jeu de structure entre articles et rubriques très simple.

L’archive zip ci-jointe ne sera pas mise à jour, elle est liée au texte de cet article, par contre le plugin est sur la zone et bénéficiera peut-être de mises à jour, voir cet article

Essayons de faire en sorte que le rédacteur ait peu de chose à se rappeler (il a déjà peut-être beaucoup à apprendre par ailleurs)...
donc pour lui, c’est tout le temps pareil :
-  pour faire un texte on fait un article.
-  on range un ou des articles dans une rubrique.
-  avec 2 niveaux maximum de rubrique, pas plus.

Considérons cette logique éditoriale comme simple...

Petite explication, si c’est utile : une rubrique n’est en ligne que si elle contient un article au moins dont le statut est publié, alors considérons une rubrique comme un dossier (sans texte ni documents) qui doit contenir au moins un article publié.

Ce que fait le squelette :
-  le menu fait apparaître les rubriques racines du site (celle du niveau 0) + cliquer le lien de la rubrique nous amène sur la page de l’article de cette rubrique, le premier article dans l’ordre du numéro du titre s’il yen a plusieurs.
-  si un seul article, il n’apparaît pas dans le menu puisque le lien de la rubrique nous amène déjà vers lui.
-  si plusieurs articles, alors ils sont listés dans le menu sous le titre de rubrique.
-  et quelques retouches de squelettes :

  • refaire le lien depuis le fil d’Ariane
  • retirer la liste des articles de la rubrique (puisqu’on les met dans le menu)
  • ...

les structures possibles :


-  rubrique (->lien vers page article + pas de sous-menu)

  • article

-  rubrique (->lien vers page article 01. + sous-menu des articles)

  • article
  • article
  • ...

-  rubrique (->lien vers page article + sous-menu des rubriques)

  • article
  • rubrique (->lien vers page article + pas de sous-menu)
    • article

-  rubrique (->lien vers page article + sous-menu des rubriques)

  • article
  • rubrique (->lien vers page article + sous-menu des articles)
    • article
    • article

s’il n’y a pas d’article dans une rubrique qui contient des sous-rubriques (par sécurité, il paraît préférable de le prévoir), le menu nous renvoi sur la page de la rubrique qui liste les sous-rubriques avec un lien chacune vers leur premier article :

-  rubrique (->lien vers page rubrique + sous-menu des rubriques)

  • rubrique (->lien vers page article + sous-menu des articles)
    • article
    • article
    • ...

le plugin nécessite SPIP en version 2.1.10 (mais devrait fonctionner avec les versions antérieures, il fonctionne aussi très bien avec SPIP 3.0.0-dev [17843]) et le plugin ZPIP-DIST

le commencement du début : un squelette dans un plugin

le B-A BA de la programmation SPIP, c’est de travailler les squelettes de son site pour le personnaliser : au sens de SPIP, les squelettes sont les modèles/templates qui vont fabriquer les pages html (en apprendre plus). Les squelettes par défaut se trouvent dans le dossier « squelettes-dist », et pour personnaliser son site on peut copier ces fichiers dans un nouveau dossier simplement appelé « squelettes », placé à la racine de son site (en apprendre plus). À partir de là, pour construire les pages, SPIP cherchera en premier lieu dans ce dossier « squelettes », s’il ne trouve pas ce dont il a besoin, il ira dans le dossier par défaut « squelettes-dist » pour trouver ce qui lui manque. Le dossier « squelettes » ne devrait donc contenir que les fichiers modifiés.

Placer les squelettes dans un plugin suppose une méthode guère plus différente, mais qui permet quelques options et facilités :
-  décrire des dépendances, des plugins nécessaires par exemple, sans lesquels le squelette ne fonctionnerait pas (ça sert d’aide mémoire si vous voulez transférer votre site)
-  le dossier de plugin rassemble tous les fichiers nécessaires, qui seraient répartis dans plusieurs dossiers avec la méthode « squelettes » traditionnelle

La méthode « plugin » commence par un dossier « squelettes » comme on le fait normalement, mais qu’on va renommer pour le reconnaître facilement : « r1r2 » pour notre exemple. Les deux grandes différences, ensuite, c’est que :
-  on va le ranger dans le dossiers « plugins » du site (le créer au besoin à la racine du site).
-  on va lui ajouter le fichier « plugin.xml » qui contiendra quelques précision sur son utilisation...
voici un exemple de ce fichier :

<plugin>
	<nom><multi>[fr]R1R2, squelette pour un site simple avec 2 niveaux de rubrique, surchage du squelette ZPIP</multi></nom>
	<icon>img_pack/r1r2.png</icon>
	<auteur>chankalan</auteur>
	<licence>GNU-GPL V3</licence>
	<version>0.1</version>
	<etat>test</etat>
	<description>
		<multi>[fr]Ce plugin installe les fichiers n&eacute;cessaires au squelette r1r2.<br />
		Il n&eacute;cessite ZPIP v1.7.9 qu'il surcharge, et un SPIP 2.1.1 minimum (mais ça devrait fonctionner sur toute version...).<br />
		C'est un point de d&eacute;part pour des sites plus complexes, et en même temps l'occasion de faire un tutoriel sur le squelette, ses boucles et ses bouclettes toutes simples &agrave; comprendre... (?)
		</multi>
	</description>

	<prefix>r1r2</prefix>

	<categorie>squelette</categorie>
	
	<necessite id="SPIP" version="[2.1.1;]" />
	<necessite id="Z" version="[1.7.9;]" />
	
</plugin>

Pour ce fichier plugin.xml, voir la suite ici et voir aussi par là...

SPIP possède les automatismes qui font qu’on a rien d’autre à faire, plus qu’à activer dans « configuration>gestion des plugins>liste des plugins » le nouveau plugin... et ses dépendances.

le début du commencement : s’organiser pour bien comprendre

Le plugin ZPIP-DIST va surcharger le squelette par défaut, le dossier squelettes-dist, pour le rendre plus facile à gérer par une imbrication de plusieurs morceaux de squelettes... voir sur la page du plugin, c’est très bien expliqué.

Lorsqu’on aura activer les deux plugins, ZPIP-DIST et r1r2 (Voir ici comment installer un plugin.), les mécanismes font que SPIP va chercher d’abord dans le squelette r1r2, ensuite dans le squelette ZPIP, et pour finir, enfin, dans le squelette par défaut, le dossier « squelettes-dist ».

Alors logiquement, chaque fois qu’on va avoir besoin d’un fichier, on ira le prendre dans le dossier du plugin ZPIP : dans le dossier /plugins/zpip si on l’a téléchargé manuellement par ftp, dans le dossier /plugins/auto/zpip si on l’a chargé automatiquement par l’interface de gestion des plugins... pour l’enregistrer dans le dossier /plugins/r1r2 ou /plugins/auto/r1r2, qui est maintenant notre dossier de squelettes.

Avec ZPIP, on peut utiliser le fichier du squelette /inclure/barre-nav.html pour construire un nouveau menu... on peut donc créer dans le dossier de notre plugin « inclure » (et créer le dossier aussi d’ailleurs) le fichier barre-nav.html

le commencement pour de vrai

Pour commencer barre-nav.html, on liste les rubriques à la racine du site, classé par numéro du titre (voir ici) et ensuite par titre :

<div class="menu rubriques">
	<ul>
	<BOUCLE_rubriques(RUBRIQUES) {racine} {par num titre, titre}>
		<li><a href="#URL_RUBRIQUE"[ class="(#EXPOSE)"]>[(#TITRE|couper{80})]</a>
		</li>
	</BOUCLE_rubriques>
	</ul>
</div>

#URL_RUBRIQUE correspond à l’url de la rubrique, qu’on va transformer pour la remplacer par l’url du premier article dans l’ordre du numéro du titre, sinon par titre. Voici la boucle qui génère l’url du premier article :

<BOUCLE_lepremierr1(ARTICLES){id_rubrique}{par num titre, titre}{0,1}>
#URL_ARTICLE
</BOUCLE_lepremierr1>

et avec le contenu alternatif, si aucun article on remet l’url de la rubrique :

<BOUCLE_lepremierr1(ARTICLES){id_rubrique}{par num titre, titre}{0,1}>
	#URL_ARTICLE
</BOUCLE_lepremierr1>
</B_lepremierr1>
	#URL_RUBRIQUE <!-- le contenu alternatif -->
<//B_lepremierr1>

Comme nous aurons besoin de cette boucle à plusieurs endroits dans nos squelettes, le plus facile est d’utiliser la méthode d’inclusion : la boucle seule doit exister dans un fichier du dossier « inclure », et c’est ce fichier qu’on appellera à chaque fois qu’on aura besoin de la boucle, comme ceci :

<INCLURE{fond=inclure/lien_rubrique,id_rubrique}>

... sans oublier le paramètre « id_rubrique » qui nous permet de calculer la boucle dans le contexte où elle se trouve, c’est-à-dire pour chaque rubrique.
Nous enregistrons donc la boucle précédente, nous disions dans notre dossier « inclure », en la nommant « lien_rubrique.html », que nous pourrons appeler, dans notre cas, depuis le fichier « barre-nav.html » :

<div class="menu rubriques">
	<ul>
	<BOUCLE_rubriques(RUBRIQUES) {racine} {par num titre, titre}>
		<li><a href="<INCLURE{fond=inclure/lien_rubrique,id_rubrique}>"[ class="(#EXPOSE)"]>[(#TITRE|couper{80})]</a>
		</li>
	</BOUCLE_rubriques>
	</ul>
</div>

en apprendre plus sur la balise INCLURE

Ensuite on a une autre boucle, pour trouver les articles et rubriques seulement lorsqu’on est déjà dans la rubrique (en fait sur une page article de la rubrique) :
-  on commence par tester la rubrique en cours :

<BOUCLE_test_expose(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}
</BOUCLE_test_expose>
	<!-- ici le contenu qui s'affiche seulement lorsqu'on est déjà dans la rubrique -->
</B_test_expose>

C’est-à-dire que si la rubrique retourne une valeur pour la balise #EXPOSE, ça veut dire qu’on y est, donc on peut mettre un contenu conditionnel, après la fermeture </BOUCLE_test_expose> et avant la fermeture du contenu conditionnel </B_test_expose>

-  à cet endroit, une boucle pour tester s’il y a plusieurs articles dans la rubrique :

<BOUCLE_test_expose(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}</BOUCLE_test_expose>

		<BOUCLE_test_article_r1(ARTICLES){id_rubrique}{1,2}>
		</BOUCLE_test_article_r1>
		<!-- ici l'inclure qui liste les articles de la rubrique, mais seulement si plusieurs articles -->
	</B_test_article_r1>

</B_test_expose>

Si le second article de la rubrique, dans n’importe quel ordre, existe, le contenu conditionnel de la boucle sera affiché. Ça revient à vérifier qu’il y a plus d’un article dans la rubrique. S’il n’y en a qu’un, on ne veut pas afficher la liste... (d’ailleurs, une liste d’un seul élément, c’est même pas une liste....)

-  avec la liste des articles en plaçant une balise <INCLURE>, le tout dans une structure ul > li :

<B_test_expose>
<ul>
<BOUCLE_test_expose(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}
</BOUCLE_test_expose>
		<BOUCLE_test_article_r1(ARTICLES){id_rubrique}{1,2}>
		</BOUCLE_test_article_r1>

		<INCLURE{fond=inclure/liste_articles,id_rubrique,id_article}>

	</B_test_article_r1>
</ul>
</B_test_expose>

Comme on le disait plus tôt, la balise <INCLURE> va chercher une petite boucle dans le dossier « inclure » qui se nomme « liste_articles.html » pour la calculer dans le contexte de notre boucle, en lui passant les paramètres id_rubrique et id_article
voici cet inclure :

<BOUCLE_articles_rubrique(ARTICLES) {id_rubrique} {par num titre, titre}>
<li><a href="#URL_ARTICLE"[ class="(#EXPOSE)"]>#TITRE</a></li>
</BOUCLE_articles_rubrique>

qui liste simplement les articles de la rubrique par numéro du titre, le paramètre id_article sert à faire fonctionner la balise #EXPOSE : lorsqu’on est sur la page d’un article, il prend la valeur « on » qui permet de le différencier des autres entrées du menu (en apprendre plus sur #EXPOSE).

Et maintenant avec les sous-rubriques :

		<B_test_expose><ul>
			<BOUCLE_test_expose(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}</BOUCLE_test_expose>
				<BOUCLE_test_article_r1(ARTICLES){id_rubrique}{1,2}>
				</BOUCLE_test_article_r1>
				<INCLURE{fond=inclure/liste_articles,id_rubrique,id_article}>
				</B_test_article_r1>

				<BOUCLE_rubriques_rubrique(RUBRIQUES) {id_parent} {par num titre} {0,10}>
				<li>
				<a href="<INCLURE{fond=inclure/lienrubrique,id_rubrique}>"[ class="(#EXPOSE)"]>#TITRE</a>
				<BOUCLE_test_expose_r2(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}</BOUCLE_test_expose_r2>
					<BOUCLE_test_article_r2(ARTICLES){id_rubrique}{1,2}>
					</BOUCLE_test_article_r2>
					<ul>
						<INCLURE{fond=inclure/liste_articles,id_rubrique,id_article}>
					</ul>
					</B_test_article_r2>
				</B_test_expose_r2>
				</li>
				</BOUCLE_rubriques_rubrique>
				
		</ul></B_test_expose>

la fin du commencement, pour ce qui concerne le menu

inclure/barre-nav.html final :

<div class="menu rubriques">
	<ul>
	<BOUCLE_rubriques(RUBRIQUES) {racine} {par num titre, titre}>
		<li><a href="<INCLURE{fond=inclure/lien_rubrique,id_rubrique}>"[ class="(#EXPOSE)"]>[(#TITRE|couper{80})]</a>
		
		<B_test_expose><ul>
			<BOUCLE_test_expose(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}</BOUCLE_test_expose>
				<BOUCLE_test_article_r1(ARTICLES){id_rubrique}{1,2}>
				</BOUCLE_test_article_r1>
				<INCLURE{fond=inclure/liste_articles,id_rubrique,id_article}>
				</B_test_article_r1>

				<BOUCLE_rubriques_rubrique(RUBRIQUES) {id_parent} {par num titre} {0,10}>
				<li>
				<a href="<INCLURE{fond=inclure/lienrubrique,id_rubrique}>"[ class="(#EXPOSE)"]>#TITRE</a>
				<BOUCLE_test_expose_r2(RUBRIQUES) {id_rubrique}>#EXPOSE{' '}</BOUCLE_test_expose_r2>
					<BOUCLE_test_article_r2(ARTICLES){id_rubrique}{1,2}>
					</BOUCLE_test_article_r2>
					<ul>
						<INCLURE{fond=inclure/liste_articles,id_rubrique,id_article}>
					</ul>
					</B_test_article_r2>
				</B_test_expose_r2>
				</li>
				</BOUCLE_rubriques_rubrique>
				
		</ul></B_test_expose>
		
		</li>
	</BOUCLE_rubriques>
	</ul>
</div>

le commencement de la fin : les derniers réglages

Lorsqu’on est sur une page d’article, le fil d’Ariane nous replace dans l’arborescence du site, en listant les rubriques, chacune cliquable pour s’y rendre rapidement... sauf que notre squelette évite d’aller dans ces pages de rubriques en remplaçant le lien par le lien des premiers articles : autant modifier ça, pendant qu’on y est...

Donc on peut récupérer le fichier /plugins/auto/zpip/contenu/article.html, c’est celui du squelette ZPIP, pour le copier dans notre plugin, en créant les dossiers au besoin /plugins/r1r2/contenu/article.html.
C’est là qu’on trouvera le fil d’Ariane et sa boucle HIERARCHIE dont on peut modifier l’url de la rubrique par celle du premier article :

[(#REM) Fil d'Ariane ]
<p id="hierarchie"><a href="#URL_SITE_SPIP/"><:accueil_site:></a><BOUCLE_ariane(HIERARCHIE){id_article}> &gt; <a href="<INCLURE{fond=inclure/lien_rubrique,id_rubrique}>">[(#TITRE|couper{80})]</a></BOUCLE_ariane>[ &gt; <strong class="on">(#TITRE|couper{80})</strong>]</p>

Si jamais (on ne contrôle jamais tout) une rubrique ne contient pas d’article du tout, mais une ou plusieurs sous-rubrique, alors le plugin place le lien de la rubrique... on se retrouve donc sur la page qu’on a cherché à éviter. On peut encore l’éditer pour la transformer légèrement, de manière à lister les sous-rubriques et renvoyer vers leur premier article...
comme pour l’article, on édite le fichier /plugins/auto/zpip/contenu/rubrique.html pour l’enregistrer dans notre plugin, dans le dossier /contenu, et on en change la liste des sous-rubriques comme ceci :

	[(#REM) Si aucun article, affiche un plan de la rubrique ]
	<B_sous_rubriques>
	<div class="menu rubriques">
		<h2 class="h2"><:sous_rubriques:></h2>
		<ul class="menu-liste">
			<BOUCLE_sous_rubriques(RUBRIQUES) {id_parent} {par num titre, titre}>
			<li class="menu-entree">
				<a href="<INCLURE{fond=inclure/lien_rubrique,id_rubrique}>">[(#TITRE)]</a>
			</li>
			</BOUCLE_sous_rubriques>
		</ul>
		</div>
	</B_sous_rubriques>

et pour finir la fin

Le fichier du squelette ZPIP /extra/article.html affiche une liste des articles de la même rubrique que l’article en cours... comme on a fait ce travail dans le fichier /inclure/barre-nav.html pour inclure ces articles au menu des rubriques, on peut tout simplement retirer cette boucle, et enregistrer le fichier dans notre dossier /plugins/r1r2/extra/article.html.
On enregistre le fichier vide, ou bien on met un commentaire <!-- /extra/article.html --> pour s’y retrouver.

On fait pareil pour le fichier « inclure/rubriques.html » qui est normalement le menu du site, nous on l’a refait dans le fichier « barre-nav.html ».

... et on peut comme ça corriger tous les squelettes qu’il faut pour rendre le site cohérent, la page /contenu/recherche.html, /contenu/mot.html, etc...

Et enfin, pour l’habillage, on peut corriger la feuille de style habillage.css et la recopier dans le dossier de plugin, mais ici on a utilisé perso.css, enregistré à la racine du plugin aussi, qui est prévue par ZPIP (le squelette zpip prévoit un appel à la feuille de style perso.css si celle-ci existe), à vous de voir si ça colle avec vos réglages...

Cette page se propose comme un tutoriel pour ceux que ça aiderait... le fichier zip qui est joint est le squelette d’exemple sous forme de plugin, c’est l’illustration de l’article : l’article et le zip sont indissociables, dans la forme qu’ils ont.

À noter que le plugin Court-circuit propose aussi de se passer des rubriques, mais d’une autre manière, et il pourrait vous être utile...

Discussion

Aucune discussion

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