Concepts
Les caches
Les caches sont des espaces secondaires de stockage de données dont le but est de fournir un accès plus rapide que le stockage principal de ces mêmes données. Un mécanisme de mise à jour des caches doit être mis en œuvre afin de suivre les modifications du stockage principal : les caches ont en général une durée de vie limitée dans le temps.
Un cache est soit un fichier soit un espace mémoire. Dans cette version du plugin Cache Factory les caches sont toujours des fichiers.
Identification complète d’un fichier cache
Le plugin Cache Factory fournit une API qui permet de simplifier la manipulation (écriture, lecture, suppression, test d’existence…) de fichiers cache pour un plugin utilisateur. Un fichier est identifié de façon unique par un chemin sur le disque. Le chemin des caches de Cache Factory est toujours formaté selon la grammaire ABNF (approximative) suivante :
<chemin> = <repertoire-plugin> [<sous-dossier>] <nom-fichier> <extension-fichier>
<repertoire-plugin> = <racine> <sous-dossier-plugin> "/"
<racine> = (_DIR_CACHE / _DIR_VAR / _DIR_TMP/ _DIR_ETC) ; const. SPIP
<sous-dossier-plugin > = ["cache-"]<prefixe-plugin> ; suivant la racine
<prefixe-plugin> = ALPHA *(ALPHA / DIGIT / "_")
<sous-dossier> = 1*(ALPHA / DIGIT / "-" / "_") "/"
<nom_fichier> = [<prefixe-nom> <separateur>] <suite-nom>
<suite-nom> = <composant> *(<separateur> <composant>)
<prefixe-nom> = 1*(ALPHA / DIGIT / "-" / "_") ; sauf le séparateur
<composant> = 1*(ALPHA / DIGIT / "-" / "_") ; sauf le séparateur
<separateur> = ("-" / "_")
<extension-fichier> = "." 1*(ALPHA / DIGIT)
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
DIGIT = %x30-39 ; 0-9
L’interprétation de la grammaire formelle permet d’édicter les règles suivantes :
- un fichier cache est toujours localisé dans un répertoire propre au plugin utilisateur (
<repertoire-plugin>
) qui est un sous-dossier des répertoires standards dans lesquels SPIP a déjà l’habitude de stocker ses propres caches (_DIR_CACHE
,_DIR_VAR
,_DIR_TMP
et_DIR_ETC
) ; - l’identification du cache à l’intérieur du répertoire du plugin utilisateur est donné par un sous-dossier facultatif et un nom qui est composé d’une série ordonnée de composants sémantiques prédéfinis et pouvant commencer par un préfixe fixe ;
- un composant du nom d’un fichier cache ne peut pas contenir le caractère séparateur utilisé.
Par exemple, les caches de N-Core sont stockés dans un dossier tmp/cache/ncore/
et se nomment <sous-dossier>/<objet>-<fonction>.php
. Cela donne pour le cache Ajax du noiZetier : tmp/cache/ncore/noizetier/type_noisette-ajax.php
. Le tiret est utilisé comme séparateur car le composant <objet>
peut contenir le caractère souligné.
Identification relative d’un cache
Pour simplifier l’identification d’un cache pour les plugins utilisateur, Cache Factory ne demande pas à chaque appel d’une API tous les éléments d’identification décrits au paragraphe précédent. La racine, le séparateur et l’extension sont des éléments invariables du chemin du fichier cache d’un plugin utilisateur donné et sont stockés dans une configuration générale.
Ainsi, connaissant le plugin utilisateur - ce qui est le cas dans chaque fonction d’API - l’identification relative d’un cache est un tableau associatif fournissant le sous-dossier - si utilisé et si différent du type de cache - et les composants, chaque composant portant une sémantique spécifique. Dans l’exemple du paragraphe précédent tiré du plugin N-Core, l’identifiant relatif coïncide avec le tableau suivant :
sous_dossier | Reçoit le préfixe du plugin utilisateur de N-Core | "noizetier" |
objet | Identifie l’objet de N-Core concerné par le cache | "type_noisette" |
fonction | Identifie le type de cache pour l’objet concerné, en l’occurrence dans notre cas, les indicateurs Ajax des types de noisette. | "ajax" |
Un plugin utilisateur doit manipuler de façon préférentielle l’identifiant relatif et rarement son chemin complet.
Les attributs des caches
Les caches fichier possèdent dans la version actuelle du plugin trois attributs : l’un indique si le cache est sécurisé (au sens de l’API SPIP), l’autre précise si le contenu est sérialisé et le dernier donne la durée de conservation du cache. Ces attributs sont stockés dans la configuration générale.
Depuis la version 0.4.2 il est possible de préciser si le contenu lu dans le cache doit être décodé avant d’être fourni. L’encodage lui reste à la charge du plugin utilisateur.
Type de cache et configuration
Le modèle de configuration des caches et la structure en composants sémantiques pour le nommage autorisent beaucoup de flexibilité pour regrouper les caches d’un plugin sous une configuration unique. Néanmoins, si un plugin utilisateur a besoin de caches JSON et PHP, ou de caches avec et sans péremption le plus efficace est de définir différentes configuration de caches.
Pour distinguer chaque configuration et associer une configuration donnée à un cache, Cache Factory définit le concept de type de cache. Un type de cache possède un identifiant unique au sein d’un plugin utilisateur composée d’une chaine alphanumérique.
C’est le couple (plugin utilisateur, type de cache) qui permet d’identifier de manière unique la configuration à appliquer à un cache. Cela a donc une incidence immédiate sur l’API de Cache Factory. Cette notion est la grande nouveauté de la branche v1 et elle introduit une incompatibilité avec la branche v0 dans laquelle la connaissance seule du plugin utilisateur permettait d’identifier la configuration à appliquer (unique pour un plugin utilisateur).
Si le sous-dossier est utilisé par le type de cache, par défaut, l’identifiant du type de cache sera affecté au sous-dossier si l’utilisateur ne le fournit pas dans l’identifiant relatif du cache. Cette évolution fonctionnelle est disponible à partir de la version 1.2.0.
API fonctionnelle PHP
La gestion des caches consiste principalement à définir le nom des caches à partir de la configuration générale pour un plugin utilisateur et de l’identification relative, et de gérer les écritures et lectures de façon à simplifier au maximum les appels et traitements de l’appelant. Aucune donnée n’est enregistrée par cache, seule la configuration générale est stockée en meta.
API : inc/ezcache_cache.php | |
---|---|
Fonctions liées aux caches | |
cache_ecrire | Ecrit un contenu donné dans un cache spécifié par son identifiant relatif ou par son chemin complet. |
cache_est_valide | Teste l’existence d’un cache sur le disque spécifié par son identifiant relatif ou par son chemin complet et, si il existe, teste si la date d’expiration du fichier n’est pas dépassée. Si le fichier existe et n’est pas périmé, la fonction renvoie le chemin complet, sinon elle renvoie une chaine vide. |
cache_lire | Lit le cache spécifié par son identifiant relatif ou son chemin complet et renvoie le contenu sous forme de tableau ou de chaine suivant l’attribut de sérialisation ou de décodage. En cas d’erreur, la fonction renvoie false. |
cache_nommer | Renvoie le chemin complet du cache sans tester son existence. Cette fonction est une encapsulation du service cache_cache_composer(). Son utilisation par un plugin appelant doit rester limitée. |
cache_repertorier | Retourne la description des caches d’un plugin utilisateur filtrée sur un ensemble de critères. La description de base fournie par Cache Factory contient les éléments de l’identifiant relatif mais peut-être remplacée ou complétée par le plugin appelant au travers de services propres. Les filtres concernent uniquement les éléments de l’identifiant relatif. |
cache_supprimer | Supprime le cache spécifié par son identifiant relatif ou par son chemin complet. |
cache_vider | Supprime, pour un plugin utilisateur donné, les caches désignés par leur chemin complet. |
Fonctions liées à la configuration | |
configuration_cache_lire | Lit la configuration générale des caches d’un plugin utilisateur ou de tous les plugins utilisateur ayant enregistrés une configuration. |
configuration_cache_effacer | Efface la configuration générale des caches d’un plugin utilisateur ou de tous les plugins utilisateur ayant enregistrés une configuration. |
L’interface utilisateur de vidage des caches
L’interface utilisateur de vidage des caches est composée d’une page dans l’espace privé, cache_vider
, et d’un formulaire listant les caches d’un plugin utilisateur donné, #FORMULAIRE_CACHE_VIDER
.
La page cache_vider
affiche les formulaires de vidage de chaque plugin utilisateur les uns sous les autres comme illustré ci-après.
Le formulaire de vidage possède un paramètre obligatoire, l’identifiant du plugin utilisateur. Le prototype est le suivant : #FORMULAIRE_CACHE_VIDER{plugin[, options]}
.
Chaque formulaire est personnalisable par plugin utilisateur en surchargeant le service de chargement des paramètres du formulaire et le sous-squelette d’affichage de la liste caches. Cette personnalisation est discutée au chapitre suivant.
Fonctionnement de Cache factory
La dissociation API – Services
Le fonctionnement global du plugin Cache Factory s’appuie sur une architecture API - services. Par conception, Cache Factory dissocie la fonction d’API, des services propres à un plugin utilisateur qui en personnalisent la gestion.
Dans le code de ses API, Cache Factory appelle donc des fonctions de service qui :
- si la fonction de service homonyme existe dans le plugin utilisateur, va l’appeler et l’utiliser ;
- sinon, va dérouler la fonction de service de Cache Factory.
L’aiguillage des services
Par conception et pour des raisons de lisibilité du code, les fonctions d’API de Cache Factory appellent systématiquement les fonctions de service de Cache Factory. Ce sont les fonctions de service de Cache Factory qui réalisent l’aiguillage vers le service souhaité ce qui leur permet aussi d’effectuer des traitements génériques et donc de limiter encore plus la complexité pour les plugins utilisateur.
Les services
Les fonctions d’API de Cache Factory font donc appel à des services dont la liste exacte est fournie ci-après. Le nom des fonctions est amputé du préfixe du plugin appelant. Ces fonctions de service ne doivent pas être appelées par le plugin appelant qui doit utiliser exclusivement les fonctions d’API. Le plugin appelant peut définir ses propres services qui seront appelés par ceux de Cache Factory, mais en aucun cas les utiliser dans son code
Services personnalisables | |
---|---|
Services de configuration | |
cache_configurer(*) | Renvoie la configuration générale des caches d’un plugin utilisateur sous la forme d’un tableau associatif dont les index sont standardisés. |
Services de gestion des identifiants de cache | |
cache_verifier | Vérifie le contenu de l’identifiant relatif du cache. Par défaut, Cache Factory complète l’identifiant avec le préfixe et le sous-dossier si nécessaire et vérifie que les composants obligatoires du nom sont bien présents. |
cache_composer | Construit le chemin complet du fichier cache à partir du tableau de l’identifiant relatif du cache. |
cache_decomposer | Décompose le chemin complet du fichier cache en éléments constitutifs. Par défaut, le tableau obtenu coïncide avec l’identifiant relatif du cache. La fonction utilise la configuration générale pour connaitre la structure du chemin du fichier. |
cache_completer | Complète la description canonique d’un cache issue du service cache_decomposer() . Le plugin Cache Factory complète la description canonique avec le nom sans extension et l’extension du fichier. |
Services de gestion du contenu d’un cache | |
cache_decoder | Effectue le décodage du contenu brut du cache (chaine) en fonction de l’extension du fichier cache. La fonction propose des traitements standard pour le JSON, YAML, et XML. Tout plugin utilisateur peut proposer sa fonction spécifique pour le format $format en codant le service cache_decoder_${format} .Il n’existe pas de service d’encodage inverse. C’est au plugin utilisateur d’encoder son contenu avant l’écriture du cache. |
cache_valider | Détermine si le cache est encore valide ou pas. Par défaut, Cache Factory vérifie l’existence du fichier cache et sa péremption pour déterminer la validité. Ces tests peuvent être compléter par le plugin utilisateur. |
Services de gestion du formulaire de vidage | |
cache_formulaire_charger | Effectue le chargement du formulaire de vidage des caches pour un plugin utilisateur donné. Par défaut, le plugin Cache Factory propose une version simplifiée du formulaire où tous les fichiers caches sont listés par ordre alphabétique sans possibilité de regroupement. |
Les services notés (*) doivent toujours être définies par le plugin utilisateur, les autres sont optionnels.
Cache Factory propose l’ensemble des services dans son fichier ezcache/ezcache.php
ce qui permet de minimiser les développements pour la plupart des plugins utilisateur. A minima, un plugin utilisateur peut se contenter de décrire uniquement sa configuration générale si il n’a aucune spécificité par rapport aux services natifs de Cache Factory.
Par exemple, le plugin Rainette définit la configuration générale de ses caches et personnalise le chargement du formulaire de vidage des caches en codant dans le fichier ezcache/rainette.php
les fonctions rainette_cache_configurer()
et rainette_cache_formulaire_charger()
.
Le pipeline post_cache
Suite à l’écriture d’une cache - fonction cache_ecrire()
– ou à sa suppression – fonctions cache_supprimer()
et cache_vider()
– Cache Factory fait appel à un pipeline nommé post_cache
. Ce pipeline permet de lancer un traitement éventuel pour conclure l’opération d’écriture ou de suppression en cours. De fait, le pipeline fournit quelques informations regroupées dans l’index ‘args’ du flux, l’index ’data’ n’existe pas.
plugin | Le préfixe du plugin utilisateur de Cache Factory. Permet à un plugin utilisateur P1 d’éviter de lancer ses traitements initiés par un plugin P2. |
fonction | Identifie la fonction générique faisant appel au pipeline. Prend les valeurs ‘ecrire’ ou ‘supprimer’. |
fichier_cache | Chemin complet du fichier cache. |
cache | Tableau canonique identifiant du cache. |
configuration | Tableau de configuration des caches du plugin utilisateur. |
Mise en œuvre dans un plugin utilisateur
Déclarer la configuration générale
Cache Factory a besoin de connaitre la configuration générale des caches d’un plugin utilisateur pour fonctionner. Le plugin utilisateur doit obligatoirement déclarer sa configuration par l’intermédiaire du service cache_configurer()
.
Le tableau associatif de la configuration à fournir par un plugin utilisateur a une structure prédéfinie qui est décrite ci-après. Le plugin utilisateur peut fournir tout ou partie de cette configuration sachant que les index non fournis seront complétés par Cache Factory avec une valeur par défaut.
Par exemple, le plugin N-Core déclare la configuration suivante :
$configuration = array(
'racine' => '_DIR_CACHE',
'sous_dossier' => true,
'nom_obligatoire' => array('objet', 'fonction'),
'nom_facultatif' => array(),
'extension' => '.php',
'securisation' => true,
'serialisation' => true,
'encodage' => false,
'separateur' => '-',
'conservation' => 0
);
Le tableau suivant récapitule l’ensemble des paramètres de configuration et leur valeur par défaut.
Paramètres de configuration | ||
---|---|---|
Paramètres fournis par le plugin utilisateur | ||
racine | Emplacement de base dans lequel sera créé le répertoire de stockage des caches du plugin utilisateur.. Les valeurs possibles sont les chaines "_DIR_CACHE" , "_DIR_VAR" , "_DIR_TMP" et "_DIR_ETC" . |
"_DIR_CACHE" |
sous_dossier | Indique si le cache est inclus dans un sous-dossier du répertoire de stockage du plugin. A partir de la version 1.2.0, si true , par défaut, Cache Factory utilise le type de cache comme nom de sous-dossier ce qui permet de ne pas le fournir dans l’identifiant du cache. Néanmoins, il est toujours possible d’écraser la valeur par défaut en le fournissant dans l’identifiant relatif du cache. |
false |
nom_obligatoire | Tableau des composants obligatoires et ordonnés du nom d’un cache. Le nom des composants sert d’index quand il s’agit de fournir le tableau identifiant un cache. | array("nom") |
nom_facultatif | Tableau des composants facultatifs et ordonnés du nom d’un cache. Les composants facultatifs suivent toujours les composants obligatoires. | array() |
separateur | Caractère de séparation de chaque composant obligatoire ou facultatif du nom. Prend les valeurs "_" , "-" ou "" si le nom est constitué d’un seul composant. Ce caractère ne doit pas être utilisé dans les composants du nom. |
"" |
extension | Extension du fichier cache. Si le fichier cache est sécurisé l’extension est toujours forcée à ".php" . |
".txt" |
securisation | Indique si le fichier doit être sécurisé ou pas. | false |
serialisation | Indique si le contenu à stocker est un tableau à sérialiser ou pas. | true |
encodage | Indique si le contenu lu est à décoder ou pas avant fourniture à l’appelant. Le type de décodage est déterminé par l’extension du fichier cache. Cette option est incompatible avec la sérialisation. | false |
conservation | Durée de conservation du cache exprimée en secondes. La valeur 0 est utilisée pour indiquer que le cache est permanent. | 0 |
Paramètres calculées par Cache Factory | ||
dossier_plugin | Répertoire de stockage du plugin calculé à partir de la racine et du préfixe du plugin. Si la racine prend la valeur "_DIR_VAR" alors le répertoire du plugin est un sous-dossier de nom "cache-${plugin}/" . Sinon, le sous-dossier porte le nom du préfixe du plugin. |
"${plugin}/" |
nom | Tableau regroupant dans l’ordre les noms obligatoires puis les noms facultatifs. | array("nom") |
Cache Factory utilise une meta nommée cache
pour stocker l’ensemble des configurations des plugins utilisateur.
Personnaliser le formulaire de vidage des caches
Cache Factory permet de personnaliser la présentation des caches d’un plugin utilisateur dans le formulaire de vidage de ces mêmes caches.
En effet, par défaut, Cache Factory affiche une liste unique de tous les caches du plugin utilisateur avec le sous-dossier, si il existe, et le nom du cache sans son extension. Les caches sont classés alphabétiquement. Cette présentation par défaut suffit au plugin N-Core mais pas à Rainette qui préfère présenter ses caches regroupés par service.
Pour permettre à Rainette et à d’autres plugins de personnaliser l’affichage, la portion du squelette qui réalise l’affichage de la liste est codée dans une inclusion. Par défaut, l’inclusion fournie par Cache Factory se nomme formulaires/inc-ezcache_cache_vider.html
. Un plugin qui souhaite « remplacer » cette inclusion doit créer sa propre inclusion nommée formulaires/inc-${plugin}_cache_vider.html
. Si elle existe elle sera appelée en lieu et place de celle par défaut.
En général, pour produire un affichage différent que l’affichage par défaut, un plugin regroupe ses caches selon certains critères et/ou rajoute des données sur chaque cache. Il est souvent nécessaire de modifier le tableau de chargement du formulaire pour qu’il coïncide avec l’objectif d’affichage.
Pour ce faire, Cache Factory propose le service cache_formulaire_charger()
. Par exemple, le plugin Rainette modifie le chargement du formulaire avec le code contenu dans la fonction rainette_cache_formulaire_charger()
.
Personnaliser les identifications et les descriptions d’un cache
Cache Factory possède des mécanismes par défaut pour composer le nom d’un fichier cache et le décomposer en composants unitaires. Ces mécanismes sont simples et non contextuels.
Pour constituer le nom d’un fichier cache le service natif cache_composer()
lit les composants attendus (obligatoires et facultatifs) et les concatène en utilisant le séparateur configuré. Pour retrouver les composants à partir du nom du fichier cache, le service natif cache_decomposer()
fait l’inverse en scindant le nom en composants. Les composants sont interprétés dans l’ordre donné par le paramètre de configuration nom
sans aucune vérification sémantique.
Ces mécanismes sont en général suffisants pour la plupart des plugins. Néanmoins, pour un plugin utilisateur qui souhaiterait personnaliser la composition ou la décomposition du nom du fichier cache, Cache Factory lui offre la possibilité de fournir ses propres services en codant les fonctions ${plugin}_cache_composer()
et ${plugin}_cache_decomposer()
qui seront utilisées en lieu et place des services natifs.
Cache Factory propose également de compléter la description d’un cache renvoyée par l’API cache_repertorier()
. La base de cette description est constituée du tableau fourni par le service cache_decomposer()
auquel Cache Factory rajoute les index « nom_cache » et « extension_cache » au travers de son service natif cache_completer()
.
De même, ce mécanisme est souvent suffisant mais un plugin comme Taxonomie a besoin de rajouter le nom scientifique du taxon concerné par un cache pour l’affichage dans le formulaire. Il code donc son propre service taxonomie_cache_completer()
pour rajouter cette information à la description retournée par cache_repertorier()
.
La validation d’un cache
Cache Factory propose des critères par défaut pour vérifier si un cache est valide ou pas. Ces critères sont l’existence du fichier cache et sa péremption (durée du cache échue comparée à sa configuration).
Néanmoins, en créant une fonction de service ${plugin}_cache_valider()
, un plugin utilisateur peut rajouter la vérification de critères propres. La fonction renvoie le résultat de la vérification sous la forme d’un booléen.
Ce service peut être utile quand la durée de conservation n’est pas un critère pertinent et que l’on veut invalider un cache sur un évènement du système (mise à jour en base de données, etc).
Utiliser le pipeline post_cache
L’utilisation du pipeline post_cache est assez rare car le plugin Cache Factory fournit par défaut déjà de nombreuses possibilités de personnalisation, en particulier concernant l’identifiant du cache. Néanmoins, certains cas sont difficilement résolubles avec les fonctions de gestion de l’identifiant car un ou plusieurs composants sont eux-mêmes calculés : il devient alors impossible de trouver une fonction réversible pour composer et décomposer le nom.
Le plugin REST Factory est confronté à ce problème : les filtres ou les ressources peuvent contenir des caractères inappropriés pour la constitution d’un nom de fichier. Pour éviter ce problème sans utiliser d’improbable conversion, ce composant nommé ‘complement’ est calculé en cryptant sa source avec un md5. Il est donc impossible de décrypter le contenu de ce complément si on veut afficher les informations sous-jacentes dans le formulaire de vidage des caches.
C’est pourquoi REST Factory utilise un index des caches créés où il stocke les éléments source ayant permis d’élaborer le nom. Il utilise cet index lors de l’affichage du formulaire de vidage des caches pour afficher les filtres ou la ressource de façon claire.
Résumé pour le développement d’un plugin utilisateur
Pour un plugin utilisateur, la mise en œuvre de Cache Factory peut se limiter à :
- créer à la racine du plugin un fichier
ezcache/${plugin}.php
; - fournir un tableau de configuration générale en codant la fonction
${plugin}_cache_configurer()
; - et utiliser les API proposées décrites de façon exhaustive sur le site de documentation du code des plugins à l’adresse suivante : https://code.plugins.spip.net/ezcache/.
Un exemple classique d’utilisation des API est donné ci-dessous (plugin Spiper Ipsum) :
// Constituer l'identifiant relatif du cache
include_spip('inc/cache');
$cache = array(
'sous_dossier' => $service,
'date' => $date,
'langage' => $code_langue
);
// Mise à jour du cache avec les nouvelles données si:
// - le fichier cache n'existe pas
// - la période de validité du cache est échue
// - le rechargement a été forcé
if ((!$fichier_cache = cache_est_valide('spiperipsum', $cache))
or (defined('_SPIPERIPSUM_FORCER_CHARGEMENT') ? _SPIPERIPSUM_FORCER_CHARGEMENT : false)) {
// Utilisation de la fonction de chargement du service.
$charger = "${service}_charger";
$tableau = $charger($code_langue, $date);
// Mise à jour du cache
cache_ecrire('spiperipsum', $cache, $tableau);
} else {
// Lecture des données du fichier cache valide
$tableau = cache_lire('spiperipsum', $fichier_cache);
}
Certains plugins voudront également personnaliser l’affichage du formulaire de vidage en codant leur version du service cache_formulaire_charger()
et de l’inclusion formulaires/inc-${plugin}_cache_vider.html
.
Ces deux personnalisations sont en général largement suffisantes pour 90% des plugins utilisateur.
Evolutions
Le plugin est dans sa phase de déploiement. Les plugins Taxonomie, Rainette, Spiper Ipsum et N-Core ont déjà adopté Cache Factory et ainsi simplifié le code de gestion de leurs fichiers cache. L’utilisation par d’autres plugins permettra surement d’envisager des améliorations à apporter à l’API actuelle.
Version 0.4.2 : le plugin REST Factory vient d’adopter aussi ce plugin et a nécessité l’ajout de l’option de décodage.
Version 0.5.0 : ajout du pipeline post_cache
.
Version 0.6.0 : renommage du préfixe et par conséquence de certains fichiers et dossiers. C’est une modification majeure qui demande une adaptation des plugins utilisateurs.
Version 0.8.2 : ajout de la constante _DIR_ETC comme répertoire d’accueil possible pour les caches.
Version 0.8.5 : ajout du service cache_valider() qui permet à un plugin utilisateur de rajouter des vérifications pour déterminer la validité d’un cache.
Version 1.0.0 : ajout du type de cache et abandon de la branche v0.
Version 1.2.0 : le sous-dossier, si utilisé, est rempli par défaut avec le type de cache ce qui permet de ne plus passer ce paramètre dans l’identifiant relatif du cache.
N’hésitez donc à partager vos retours.
Aucune discussion
Ajouter un commentaire
Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :
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.
Suivre les commentaires : |