Un flux RSS par Keyword (ou autre) sur eZ Publish
- Publié le 17 Mars 2009
- 9 commentaire(s)
- Catégorie : Technologies Web
Pour le besoin de certains "planet", comme par exemple l'excellent http://www.planet-ezpublish.fr/ ou l'international http://www.planetezpublish.org/, il me fallait produire un RSS spécifique à eZ Publish. La solution la plus simple consiste à exploiter les keywords (voir le nuage de tags) pour lister tous les articles spécifiques à eZ Publish, dans un flux RSS sur mesure.
De nombreuses techniques ou extensions ont déjà été publiées pour la fabrication des RSS sur mesure, comme par exemple l'article de Tigrou. Il existe finalement mille et une façon de procéder, j'ai donc tenté de battre le record du plus gros fainéant en produisant ce RSS avec le moins de code possible...
Le principe général
La technique est triviale, il s'agit de créer une Classe de contenu spécifique aux fils RSS. Ensuite chacun des noeuds de contenus créés à partir de la classe doit proposer une vue de type RSS et non de type XHTML.
La technique est puissante et évolutive, puisqu'elle permet d'enrichir sa classe pour propager des paramètres vers les templates, afin de produire une infinité de RSS selon tel ou tel critère. La technique peut évidemment s'étendre au XML, par exemple pour la production de contenus exploitables par un Widget ou autres moteurs de syndication.
La classe "RSS"
| Attributs | Datatype |
|---|---|
| Titre (title) | Ligne de texte |
| Description (description) | Ligne de texte |
| Nombre d'items (limit) | Nombre entier |
C'est une classe minimale, souvent suffisante. On peut ensuite l'enrichir avec d'autres attributs utilisés comme des paramètres, comme par exemple : la profondeur, des filtres, un délai d'expiration du cache, l'affichage des billets résumés ou complets, etc...
Les surcharges de templates
Il suffit de créer les templates suivants dans /extension/[mon_extension]/design/[mon_design]/override/templates/rss/ :
- rss_pagelayout.tpl (pour le layout XML, en-tête XML)
- rss_full.tpl (pour le contenu du flux RSS, c'est à dire la liste des items)
- rss_link.tpl (pour la gestion des liens absolus http://www.gandbox.fr/...)
Il faut ensuite définir les surcharges dans le fichier /extension/[mon_extension]/settings/siteaccess/[mon_siteaccess]/override.ini.append.php :
[rss_pagelayout] Source=pagelayout.tpl MatchFile=rss/rss_pagelayout.tpl Subdir=templates Match[class_identifier]=rss [rss_full] Source=node/view/full.tpl MatchFile=rss/rss_full.tpl Subdir=templates Match[class_identifier]=rss [rss_link] Source=content/datatype/view/ezxmltags/link.tpl MatchFile=rss/rss_link.tpl Subdir=templates Match[class_identifier]=rss
Les templates
Le template "rss_pagelayout.tpl"
<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> <channel> {$module_result.content} </channel> </rss> <!--<!--DEBUG_REPORT-->-->
A noter : le double commentaire sur le DEBUG_REPORT permet de neutraliser la sortie du debug dans un commentaire XHTML. C'est appréciable en version de développement pour obtenir un RSS valide.
Le template "rss_full.tpl"
{set-block scope=global variable=cache_ttl}600{/set-block} {def $title_rss = $node.data_map.description.content $siteurl = concat('http://',ezini('SiteSettings', 'SiteURL'))} {if is_set($view_parameters.tag)} {def $billets_list = fetch( 'content', 'keyword', hash( alphabet, $view_parameters.tag, 'classid', array(24), 'sort_by', array( array( 'published', false() ) ), 'limit', $node.data_map.limit.content ))} {set $title_rss = concat($title_rss, ' - ', $view_parameters.tag)} <title>{$title_rss}</title> <description>{$title_rss}</description> <lastBuildDate>{$billets_list[0].link_object.object.published|ezrssdate()}</lastBuildDate> <link>{$node.url_alias|ezurl('no','full')}</link> {foreach $billets_list as $item} <item> <title>{$item.link_object.name|wash}</title> <description>{$item.link_object.data_map.intro.content.output.output_text|wash()}{$item.link_object.data_map.text.content.output.output_text|wash()}</description> <pubDate>{$item.link_object.object.published|ezrssdate()}</pubDate> <link>{$siteurl}/{$item.link_object.url_alias}</link> </item> {/foreach} {/if} {undef $billets_list $title_rss $siteurl}
A noter : la directive set-block permet de fixer un temps d'expiration du cache. Dans cet exemple, la page expire chaque 10 minutes (600 secondes), ce qui est largement suffisant pour un RSS.
A noter : l'opérateur de template ezrssdate(), voir plus bas dans le billet le focus sur ce cas particulier
Le template "rss_link.tpl"
<a href={$href|ezurl(,'full')}{section show=$id} id="{$id}"{/section}{section show=$title} title="{$title}"{/section}{section show=$target} target="{$target}"{/section}{section show=ne($classification|trim,'')} class="{$classification|wash}"{/section}>{$content}</a>
A noter : Il s'agit simplement d'ajouter au template link.tpl la directive 'full' pour générer les URL absolues.
Les dates au format RSS
Le problème quand on est Français, c'est qu'on publie un Blog en Français, et eZ Publish nous génère donc des dates en Français. Hors le format RSS nécessite des dates sur un format Anglais : Sun, 01 Mar 2009 20:45:15 +0100 et non pas Dim, 01 Mar 2009 20:45:15 +0100.
Certes il existe l'opérateur natif l10n, mais cet opérateur ne propose pas le format RSS. Il faut donc définir soit même ce format dans un fichier custom (par exemple /share/locale/eng-GB@rss.ini) :
- DateTimeFormat=%D, %d %M %Y %H:%i:%s %O
Cette technique pose tout de même le problème de la localisation du fichier, qui n'est pas présent dans l'extension principale... Technique peu acceptable, à abandonner.
L'opérateur ezrssdate
Le plus simple reste la création d'un opérateur de template. Par ailleurs depuis PHP 5.1.1+ le format RSS existe en natif, ce qui simplifie encore un peu le code (parfait pour les fainéants).
<?php class eZRssDate { function eZRssDate() { } function operatorList() { return array( 'ezrssdate' ); } function namedParameterPerOperator() { return true; } function namedParameterList() { return array( 'ezrssdate' => array( true )); } function modify( $tpl, $operatorName, $operatorParameters, &$rootNamespace, &$currentNamespace, &$operatorValue, &$namedParameters ) { $operatorValue = date(DATE_RSS, $operatorValue); //PHP 5.1.1 + } } ?>
Le résultat
Flux RSS des billets eZ Publish
- Tags :
- RSS
- eZ Publish
- Template Operators
Que boire avec ce billet ?
Château de Jonquieres - Blanc Sec 2005
| Région : | Languedoc |
| Appellation : | Vin de Pays de l'Hérault |
| Domaine : | Château de Jonquieres |
| Couleur : | |
| Stock : | 0 |
| Notation : | |
| Prix : | 12 € |
| Commentaire(s) : | 0 Commentaire(s) |
RSS
Encore une fois un très bon article!
Language ?
Salut,
J'ai développé à peu de choses près ceci pour http://www.wascou.org sauf que j'ai ajouté un paramètre pour la langue. Mais sinon good job !
Max
Petites remarques :)
Au niveau du format de la date, tu dois pouvoir t'en sortir avec l'opérateur datetime() [1] / le fichier datetime.ini au lieu de modifier un fichier de noyau ou de définir un nouvel opérateur.
Sinon au niveau du cache tu peux aussi éviter de manipuler la variable cache_ttl (c'est une catastrophe en terme de perf) en utilisant le SmartCache dans le fichier viewcache.ini [2] en le configuration pour vider le cache de contenu de l'objet "rss2" quand tu ajoutes/édites un billet. Comme ça, le cache de contenu est vidé uniquement lorsque nécessaire et pas toutes les 10 minutes ce qui peut une énorme différence en fonction de l'utilisation du flux RSS.
[1] http://ez.no/doc/ez_publish/techn...ng_and_internationalization/datetime
[2] http://ez.no/doc/ez_publish/techn...ew_caching/smart_view_cache_cleaning
datetime et cache
Concernant l'opérateur "datetime" :
Sauf erreur, il ne permet pas de forcer l'utilisation de l'anglais, et on obtient donc des "Sam" plutôt que des "Sat"... A l'inverse l'opérateur l10n permet de forcer arbitrairement une langue, mais propose seulement quelques formats de dates (pas le RSS, pas de propriété custom comme datetime)... Donc impasse et donc opérateur...
Concernant le cache :
L'utilisation du SmartViewCache est bien sûr possible, mais nécessite de fixer "en dur" l'object ID (AdditionalObjectIDs), ce qui ne me convient pas du tout pour X raisons de généricité.
Le "set-block" sur 10 minutes est à titre d'exemple. Forcer le vidage du template toutes les nuits est généralement suffisant. D'ailleurs je n'utilise pas vraiment cette technique sur gandbox.fr, puisque j'ai un edithandler pour toutes les manipulations de caches non gérables par le SmartViewCache... mais je préfère proposer des techniques de feignants ![]()
En parlant de cache
En parlant de cache...
Je me demandais comment ca marche tous ce truc et quelle lien il y a entre le view cache et les cache-block.
J'avoue que pour moi tout ça est très confut.
Si tu as des articles solide sur le sujet ca m'intéresse!
Gné?
pfff, je comprends rien à tes posts!
A quand un qui traite de l'optimisation SQL sous eZ?
=>|
Bon allez, j'ai fait mon quota de commentaires inutiles ![]()
Content Type
Salut,
Très bonne article et excellente idée. J'en prends exemple pour l'adapter à ma sauce. Par contre comment tu fais pour fixer ton content type sans passer par le layout.ini ?
Si je suis à la lettre ton article en modifiant seulement le override..ini, je me retrouve avec une page en content type text/html.
J'ai loupé un truc?
Merci,
Nicolas
Content Type XML ou HTML
Le XML que tu génères est peut être invalide, ou le RSS n'est pas correctement formé pour permettre une auto détection par le navigateur.
XML et navigateurs
L'interpretation du flux RSS depend des naviagteurs,
Par exemple toute les versions de FF ne savent pas forcément traiter un flux RSS balancé en Content-Type: text/html
Pour un traitement impécable, il vaut mieux spécifier le content-type correct: application/rss+xml
