Ça fait quelques mois, voire plutôt quelques années, que j’ai en tête une extension de la gestion des filtres globaux des balises de template. Vous savez, comme quand dans un billet tronqué on utilise l’attribut cut_string="300" par exemple :
<p>
{{tpl:EntryContent encode_html="1" remove_html="1" cut_string="300"}}
<tpl:EntryIfContentCut encode_html="1" remove_html="1" cut_string="300">
<span class="ellipsis"> […]</span>
</tpl:EntryIfContentCut>
</p>
En fait j’avais en tête de développement de filtres tiers, comme gracefulCut qui permettrait de remplacer le comportement prévu du filtre cut_string, un peu barbare dans sa façon de couper, par une découpe un peu plus intelligente.
Sauf que le système des behaviors prévu par Dotclear rend ça assez compliqué, surtout qu’en essayant de palier des problèmes de passage de paramètres de fonction par référence plutôt que par valeur, en utilisant des ArrayObject, il s’avère que ce n’est pas supporté de la même manière en fonction des installations[1].
Du coup j’ai remis ça à plat et suis parti sur une autre direction, en m’inspirant des filtres antispam qui, lorsqu’ils sont sollicités, retournent une valeur indiquant s’il faut continuer à appliquer les filtres suivants ou si une décision (spam ou pas) a été prise par le filtre.
Je pense que je suis le seul, pour l’instant, à avoir développé un filtre nouveau (gracefulCut, censé prendre la place de cut_string dans certains cas), et par conséquent j’ai les mains libres pour faire un peu ce que je veux ;-)
J’envisage donc de mettre en place un mécanisme permettant d’enregistrer un filtre nouveau (pas encore développé[2]) et de faire appliquer des filtres par des plugins tiers, ceux-ci ayant la charge d’indiquer s’il faut ensuite stopper le traitement pour ce filtre ou poursuivre avec le traitement par défaut — pour les filtres standards de Dotclear, j’entends.
Donc dans tous les cas, l’appel du nouveau behavior publicContentFilter devra retourner un '1'
pour stopper le traitement, ou n’importe quoi d’autre pour le poursuivre.
Avec ça le plugin gracefulCut pourrait lors de l’application du filtre cut_string, qu’il est censé remplacer dans certains contextes, annuler l’application du filtre standard, un peu bourrin.
La nouvelle fonction ressemble donc maintenant à ça :
public static function global_filters($str, $args, $tag = '')
{
$filters = array(
'strip_tags', // Removes HTML tags (mono line)
'remove_html', // Removes HTML tags
'encode_xml', 'encode_html', // Encode HTML entities
'cut_string', // Cut string (length in $args['cut_string'])
'lower_case', 'capitalize', 'upper_case', // Case transformations
'encode_url' // URL encode (as for insert in query string)
);
$args[0] = &$str;
# --BEHAVIOR-- publicBeforeContentFilter
$res = $GLOBALS['core']->callBehavior('publicBeforeContentFilter', $GLOBALS['core'], $tag, $args);
$str = $args[0];
foreach ($filters as $filter) {
# --BEHAVIOR-- publicContentFilter
switch ($GLOBALS['core']->callBehavior('publicContentFilter', $GLOBALS['core'], $tag, $args, $filter)) {
case '1':
// 3rd party filter applied and must stop
break;
case '0':
default:
// 3rd party filter applied and should continue
// Apply default filter
if ($args[$filter]) {
$str = self::default_filters($filter, $str, $args[$filter]);
}
}
}
# --BEHAVIOR-- publicAfterContentFilter
$res = $GLOBALS['core']->callBehavior('publicAfterContentFilter', $GLOBALS['core'], $tag, $args);
$str = $args[0];
return $str;
}
Ça devrait faire le job, je pense, à moins que vous n’ayez d’autres meilleures idées ?
Notes
[1] Je sais que c’est indépendant de la version de PHP, et je ne sais toujours pas expliquer cette différence de comportement.
[2] D’ailleurs je ne suis pas certain que ce soit pour l’instant indispensable vu qu’il est déjà possible de les gérer aujourd’hui, le plugin gracefulCut et son filtre graceful_cut="180" en est un bon exemple.
1 De Philippe -
Si j’ai bien compris, avec ce nouveau comportement, on pourra ensuite développer un plugin qui coupe comme on le veut, soit par exemple qui supprime certaines balises et pas d’autres ?
\o/\o/\o/
2 De Gilsoub -
J’ai rien compris, mais c’est super puisque cela fait avancer Dotclear ;-) alors merci :-)
3 De Franck -
Philippe, « … soit par exemple qui supprime certaines balises et pas d’autres … », pas des balises non mais des filtres (attributs) dans les balises, oui.
Pour les balises (éléments ou blocs) il y a déjà ce qu’il faut côté behaviors.
4 De Franck -
Ou alors tu parles des balises présentes dans la chaîne de caractère à découper, alors dans ce cas oui :-)
5 De Philippe -
Je parlais bien de supprimer certaines balises (<img/> ou <a> par exemple) dans la chaîne à découper, oui :)