Créer un modèle permettant de calculer l’âge automatiquement

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

Pouvoir calculer un âge et afficher le résultat automatiquement dans un article, un titre, une brève, etc.
L’âge est mis à jour dynamiquement et automatiquement.
Cet article vous explique pas à pas comment y arriver.

Pré-requis : (conseillé)

  • Connaître un peu de php
  • Connaître un peu de html

Cet article est destiné à : webmestre

Introduction

Nous allons créer, ensemble, un modèle Spip permettant de calculer un âge automatiquement.

Spip, nous permet, facilement, de créer ses propres modèle afin d’ajouter des fonctionnalités.

Qu’est-ce qu’un modèle ?

Je renvoie vers la documentation de Spip qui est, selon moi, la plus appropriée pour l’expliquer : Utiliser les modèles.

Il nous faut savoir deux trois choses sur les modèles avant de faire le nôtre :

  • Les modèles créés ou rajoutés doivent être dans le dossier « modeles » lui-même, dans le dossier « squelettes ».
  • Les modèles sont sous forme de fichier html.
  • Les modèles portent le même nom que la syntaxe correspondante dans Spip
  • S’il doit y avoir des actions en php, le fichier (php) doit avoir le même nom que le fichier html avec _fonctions.php à la fin. Exemple, si notre modèle se nomme modele1.html le fichier contenant les fonctions php aura pour nom : modele1_fonctions.php [1].
  • Pour agir, avec un script php, sur un modèle qui, lui est en html, on utilise un filtre php. Les filtres sont à appliquer sur un champ (exemple : [(#TEXTE|filtre)]).
  • Si le modèle doit faire appel à un code php spécifique, celui ci doit être créé sous la forme de fonctions qui seront appelées comme filtres dans le squelette html du modèle. Cette définition peut se faire dans un fichier du même nom que le fichier html, mais suffixé par « _fonctions.php » et situé dans le même dossier que lui. Exemple, si notre modèle se nomme age.html le fichier contenant les fonctions php aura pour nom : age_fonctions.php [2].

Concrètement :

Note : vous trouverez, à la fin de l’article, le modèle déjà prêt.

Nous allons commencer par créer le répertoire « modeles », s’il n’existe pas déjà, ensuite nous allons partir d’une syntaxe, d’une forme d’écriture que Spip reconnaîtra et qui appellera notre modèle.
Nous partirons sur la syntaxe suivante :

<ages|n=date>

« date » sera, évidemment, à remplacer par la date « d’anniversaire » souhaité, par exemple, si l’on veut dire :

J’utilise Spip depuis ... ans

On écrira :

J'utilise Spip depuis <ages|n=13-02-2011> ans

Le modèle

Maintenant qu’on a notre syntaxe, on peut commencer le modèle, pour cela on va créer un fichier, toujours dans le dossier modeles, nommé ages.html (sans les guillemets). Dans ce fichier il faut écrire les morceaux de html dont vous avez besoin (c’est un mini squelette).
Pour notre modèle nous n’avons pas besoin de balise html, on va juste écrire :

[(#ENV{n}|ages)]

Je vous explique, lorsque, dans Spip, nous avons écrit <ages|n=date> on affecte à la variable, ici, n la valeur date. Afin de récupérer cette valeur, Spip nous propose une syntaxe qui est la suivante :

#ENV{nom_de_la_variable}

Ensuite, sur cette variable nous appliquons un filtre nommé ages (c’est le |ages).

Comment ce filtre fonctionne ?

Spip va appeler une fonction php du même nom, ici ages.

C’est là qu’on créer le fichier php nommé « ages_fonctions.php »

Pourquoi ce fichier doit s’appeler ages_fonctions.php

SPIP permet, par cette dénomination, d’associer un fichier php à un squelette. Notez que si on partage des filtres entre plusieurs squelettes, on utilise mes_fonctions.php.

Dans ce fichier nous allons créer une fonction nommée ages. Notre fichier php commence par <?php et fini par ?>.
Ensuite, on déclare la fonction et on lui met en paramètre une variable qui contiendra la date :

function ages($uneDate) {
	// C'est ici que l'on va écrire le code permettant de calculer l'âge
}

En appliquant le filtre sur #ENV{n}, le paramètre $uneDate va prendre la valeur de #ENV{n} donc de la date stocké dans le paramètre d’environnement n.

Le double slash (//) désigne un commentaire. Un commentaire est un morceaux de code qui n’est pas exécuté, il est souvent utilisé pour aider le développeur dans la compréhension du code.

Dans le cas présent, j’ai décidé de faire une vérification sur la date, afin d’être sûr qu’elle soit au bon format et, ainsi, éviter d’éventuels bogues.
Nous allons commencer par déterminer une chaîne de caractère type (à l’aide des expressions relationnelles : regexp). Je renvoie vers l’article correspondant sur Wikipédia : Expression rationnelle

Voici deux variables, contenant une fonction php permettant de vérifier la présence d’une chaine de caractère (ici notre regexp) :

	// Vérifie la présence d'une chaîne type dans la date (vérifie le format de la date)
	$test1 = preg_match("/(^[0-9]{2})[-\/]([0-9]{2})[-\/]([0-9]{4}$)/", $uneDate);
	$test2 = preg_match("/(^[0-9]{4})[-\/]([0-9]{2})[-\/]([0-9]{2}$)/", $uneDate);

J’utilise la fonction « preg_match », elle fonctionne de la manière suivante :

preg_match("la chaine recherchée", "la chaîne dans laquel on va rechercher la chaîne recherchée", $une_Variable_Contenant_Les_Éventuels_Résultats);

Je vais tenter de vous expliquer une des expressions relationnelles :

/(^[0-9]{2})[-\/]([0-9]{2})[-\/]([0-9]{4}$)/

Les parenthèses désignent un groupe, dans le premier groupe

(^[0-9]{2})

on note la présence d’un accent circonflexe juste avant les crochets [0-9]. L’accent nous indique que l’on peut trouver ce qui suit uniquement en début de ligne, en l’occurrence [0-9] qui désigne n’importe quel chiffre de 0 à 9 (par exemple 4). Après les crochets, il y a des accolades :

{2}

elles indiquent le nombre de fois que l’on doit trouver l’expression juste avant celle-ci (les accolades). Ici

[0-9]{2}

signifie que l’on doit trouver deux chiffres allant de 0 à 9.

Après les premières parenthèses, il y a des crochets ([-\/]) ils signifient qu’il doit y avoir, après les deux chiffres, le caractère « - » ou le caractère « / » [3].

Le dollar « $ », juste avant la dernière parenthèse, signifie que l’expression juste avant doit se situer absolument en fin de ligne, il ne doit rien y avoir derrière).

Maintenant, vous êtes tout à fait capable de comprendre l’expression relationnelle.

Pourquoi avoir fait deux regexp ?

Si vous avez compris et que vous regardez attentivement, vous trouverez facilement la raison. J’aurais très bien pu faire un seul regexp mais j’ai voulu m’assurer que la date donnée soit bien au format Année/Mois/Jour ou Jour/Mois/Année. La première expression cherche : 00-00-0000 (comme en français) et la seconde : 0000-00-00 (comme en SQL). Ici, les zéros désignent n’importe quel chiffre de 0 à 9.

Nous allons, maintenant, pouvoir écrire le test conditionnel qui vérifiera le format de la date, donc :

	if ($test1 or $test2) {
		// Calcule l'âge
	} else {
		// Retourne la phrase : Format de date invalide : "la date en question";
	}

Traduction :
Si (if) le test1 a trouvé une correspondance OU (or) que le test2 a trouvé une correspondance, alors, on calcule l’âge. Sinon (else) on retourne une phrase d’erreur.

Voici le teste conditionnel complet :

	if ($test1 or $test2) {
		// Calcule l'âge
		$age = date('Y') - date('Y', strtotime($uneDate));
		if (date('md') < date('md', strtotime($uneDate))) {
			$age = $age - 1;
		}
	} else {
		return("<b>Format de date invalide : ".$uneDate."</b>");
	}

Explication :
En ligne 3, on a le cœur de la fonction, la base de notre modèle, c’est à dire le calcul de l’âge. Cette ligne veut dire : la variable, du nom de $age, prend la valeur de l’année actuelle moins la valeur de l’année donnée, stocké dans la variable nommée $uneDate.

De la ligne 4 à 6, on voit un autre test conditionnel, permettant de vérifier que la date d’anniversaire n’est pas passée. Dans ce cas, il retire un an à l’âge afin que celui-ci soit juste.

En ligne 8, on a le retour en cas d’erreur. Le mot clef return renvoie la chaîne de caractère donné (notez la présence des balise html <b> et </b> qui permettent de mettre ce qu’elles contiennent en gras) et stoppe l’exécution de la fonction.

J’ai rajouté à la chaîne de caractère la date contenu afin que l’utilisateur puisse se rendre compte de son erreur.

Maintenant, il ne reste plus qu’à retourner l’âge et notre fonction est terminée.
Voici le retour de l’âge :

	// Revoit l'age.
	return($age);

Fini !

Voici la fonction en entier :

<?php
/********************************** age **********************************
*	Cette fonction permet de calculer un âge et de l'afficher dans un
*	article, une rubrique, une brève, etc.
*
*	La syntaxe est la suivante :
*		<ages|n=date>
*
*	Exemples :
*		<ages|n=2000-01-01>
*		<ages|n=01-01-2000>
*
*	Formats de date supportés :
*		AAAA-MM-JJ
*		AAAA/MM/JJ
*		JJ-MM-AAAA
*		JJ/MM/AAAA
*
*	Auteur	: Gaël de Weerdt
*	Version	: 0.0.1
*	Date		: 13 Février 2015
*
*************************************************************************/

	function ages($uneDate) {
		// Vérifie la présence d'une chaîne type dans la date (vérifie le format de la date)
		$test1 = preg_match("/(^[0-9]{2})[-\/]([0-9]{2})[-\/]([0-9]{4}$)/", $uneDate);
		$test2 = preg_match("/(^[0-9]{4})[-\/]([0-9]{2})[-\/]([0-9]{2}$)/", $uneDate);

		if ($test1 or $test2) {
			// Calcule l'âge
			$age = date('Y') - date('Y', strtotime($uneDate));
			if (date('md') < date('md', strtotime($uneDate))) {
				$age = $age - 1;
			}
		} else {
			return("<b>Format de date invalide : ".$uneDate."</b>");
		}

		// Revoit l'age.
		return($age);

	}
?>

Récapitulatif

Nous avons choisi une syntaxe pour Spip, nous avons créé le modèle avec le fichier ages.html, dans lequel nous avons appliqué un filtre (la fonction php ages du fichier ages_fonctions.php) et nous avons écrit la fonction. Et le tout est au bon endroit (dans le dossier modeles" qui est dans le dossier « squelettes »).

Le modèle devrait être fonctionnel, il ne reste plus que l’essayer !

Conclusion

Nous avons créé notre propre modèle qui calcule l’âge automatiquement, le met à jour et il fonctionne très bien !

C’est maintenant à vous de faire vos modèles afin d’améliorer votre Spip :

Téléchargement du modèle

modeles-ages
Version officielle de cette contribution pédagogique.
modeles-ages_v0.0.2
Nouvelle version bien différente permettant de calculer et d’afficher l’âge avec l’année, les mois et les jours ainsi que la gestion des pluriels etc..
Exemple : Âge : 1 an, 20 mois et 2 jours

Notes

[1Si les actions sont partagés entre plusieurs modèles, on utilisera alors mes_fonctions.php

[2Si les actions sont partagés entre plusieurs modèles, il faudra utiliser le fichier généraliste mes_fonctions.php

[3L’antislash « ~ » juste avant le slash « / » permet d’annuler l’effet du slash dans le regexp afin qu’il soit compté comme un caractère lambda.

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