Afficher des flux RSS provenant d'autres sites
Besoins
On doit pouvoir faire une nouvelle "action" wikini qui s'insère, par exemple, dans n'importe quelle page sous la forme :
{{readRSS backend="http://www.wakkawiki.com/xml/recentchanges_wakkawiki.xml"}}
WikiNi est utilisé dans certains cas pour gérer des sites complets et cette fonctionnalité peut, dans ce cas, trouver d'intéressants usages :
- affichage sur un portail des nouvelles des sites liés à ce portail
- enrichissement d'un tableau de bord où l'on peut alors gérer plusieurs wikis : l'expérience montre que souvent un animateur de wiki anime plusieurs wikis
- affichage des nouvelles du site d'un blogueur participant au wiki (pratique courrante sur CraoWiki)
- affichage d'une page de synthèse pour les "veilleurs", en ligne, sans avoir à s'abonner à un service ou s'enregistrer et sans avoir à se déplacer avec son agrégateur favori
--
CharlesNepote
Solution avec la bibliothèque EasyRSS
Avec la bibliothèque
EasyRSS, j'obtiens des résultats satisfaisants. Pour tester, j'ai créé l'action rss.php ci-dessous, en quelques secondes, à partir du fichier fournit en exemple :
<?php
// ------------------------------------------------------------------------- //
// exemple2.php - parser le fichier des news de Phpinfo.net et afficher //
// ------------------------------------------------------------------------- //
// Copyright (C) 2001-2002 Philippe RODIER <webmaster@phpspirit.com> //
// ------------------------------------------------------------------------- //
// PHPSPIRIT <http://www.phpspirit.com/> //
// ------------------------------------------------------------------------- //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program; if not, write to the Free Software //
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //
// ------------------------------------------------------------------------- //
// la classe easyRSS
include('easyRSS.inc.php');
// créer l'instance
$phpinfo_rss = new easyRSS();
// parser le fichier news sur phpinfo.net et limiter à 20 news max
// soyez connecté au web :)
$phpinfo_rss -> parsefile("http://nospoon.org/backend_rdf.xml", 20);
// on s'amuse à afficher les infos (cad les news) avec une petite mise en page
echo "
<table bgcolor=\"#cccccc\" >
<tr>
<td height=\"40\">
<div align=\"center\">
<a href=\"".$phpinfo_rss -> get_image_link()."\">
<img src=\"".$phpinfo_rss -> get_image_url()."\" width=\"".$phpinfo_rss -> get_image_width()."\"
height=\"".$phpinfo_rss -> get_image_height()."\" border=\"0\"
alt=\"".$phpinfo_rss -> get_image_title()."\">
</a>
</div>
</td>
</tr>
<tr>
<td>
";
$nbnews = $phpinfo_rss -> get_num_items();
$news_title = $phpinfo_rss -> get_items_title();
$news_link = $phpinfo_rss -> get_items_link();
for($i=1;$i<=$nbnews;$i++)
{
echo "· <a href=\"".$news_link[$i]."\" target=\"_blank\">".$news_title[$i]."</a><br />\n";
}
echo "</td>
</tr>\n";
if($phpinfo_rss -> exist_textinput())
{
echo "<tr>
<td>
<br>
<form method=\"get\" action=\"".$phpinfo_rss -> get_textinput_link()."\">
".$phpinfo_rss -> get_textinput_description()."
<input type=\"text\" name=\"".$phpinfo_rss -> get_textinput_name()."\"
size=\"10\" maxlength=\"10\"> <input type=\"submit\" name=\"Submit\"
value=\"".$phpinfo_rss -> get_textinput_title()."\">
</form>
</td>
</tr>";
}
echo "</table>\n";
//exit();
?>
Dans cet exemple, le lien vers le flux RSS est codé en dur, mais il ne doit pas être difficile de le passer en paramètre.
--
CharlesNepote
Note : au moment de ces tests j'avais noté des problèmes que j'ai aujourd'hui oublié. C'est la raison pour laquelle je me suis tourné vers la bibliothèque
MagPie? (voir ci-dessous), très riche et bien suivie.
A faire : lister les contraintes de cette solution : pré requis, contraintes, etc.
--
CharlesNepote
Solution avec la bibliothèque MagPie?
Pré-requis :
- fonctionne avec PHP 4.2 (pas testé avec d'autres versions)
Avantages :
- gère RSS 0.9-1.0-2.0 et Atom
- gestion transparente d'un cache (fixé à une heure par défaut)
- très simple d'emploi
Cette méthode est fonctionnelle avec la version 0.61 de
MagPie? RSS.
- télécharger la bibliothèque en version 0.61
- décompacter à la racine de wikini
- ajouter l'action ci-dessous et c'est fini
Exemple d'usage :
{{rss url="http://conforme.phidji.com/database/index.rdf" class="right solid_border gray_background small_fonts height15em"}}
Ce premier jet de code est améliorable mais il fonctionne correctement.
Amélioration possibles :
- stylage des puces
- agrégation de plusieurs flux, les items de chaque flux étant mélangés et classés par ordre chronologique (un peu comme des courriels provenant de différentes personnes)
- logo du site
- réglage du temps de cache
<?php
// rss.php version 0.2 du 24/05/2004
// Action pour WikiNi 0.4.1rc et supérieurs
// Permet d'afficher un flux RSS
//
// Paramètres :
// -- url : URL du flux à afficher (obligatoire)
// -- class : nom de la classe de style à inclure (facultatif)
//
// copyrigth Charles Népote malito:charles02@nepote.org
//
// Licence GPL, vous êtes libre d'utiliser et de modifier ce code à condition de
// laisser le copyright d'origine. Vous pouvez bien sur vous ajouter à la liste
// des auteurs.
// Installation
// - copier le fichier dans le repertoire "actions" de WikiNi
// - installer magpierss-0.61 dans la racine de wikini
//
require_once '/../magpierss-0.61/rss_fetch.inc';
if (!$this->GetParameter("url"))
{
echo
"<p>Vous devez spécifier une adresse à l'aide du paramètre \"url\".</p>",
"<p>Par exemple : <pre>{{rss url=\"http://example.org/flux.rss\"}}</pre></p>";
}
else
{
$url = $this->GetParameter("url");
// Code de lecture des classes de style pompé sur l'action include
if ($this->GetParameter("class"))
{
$array_classes = explode(" ", $this->GetParameter("class"));
foreach ($array_classes as $c)
{
$classes = $classes . "include_" . $c . " ";
}
}
$rss = fetch_rss($url);
// Calcul des items
//
foreach ($rss->items as $item)
{
$title = $item[title];
$url = $item[link];
$output .= "<li><a href=$url>$title</a></li>\n";
}
// Calcul du titre
//
if ($rss->channel['link'])
{
$title = "<a href=\"".$rss->channel['link']."\">".$rss->channel['title']."</a>";
}
else
{
$title = $rss->channel['title'];
}
// Affichage
//
echo "<div class=\"", $classes, "\">\n",
"<p>Site : ", $title, "</p>\n",
"<ul>\n",
$output,
"</ul>\n",
"</div>\n";
}
?>
Pour ceux qui veulent modifier la valeur du cache par défaut, il faut modifier la ligne suivante dans le fichier
/magpierss-0.61/rss_cache.inc
var $MAX_AGE = 3600; // when are files stale, default one hour
Pour ceux qui sont derrière un proxy, il faut aller configurer à la main les valeurs du proxy dans le fichier
/magpierss-0.61/extlib/Snoopy.class.inc.
--
CharlesNepote
ça fonctionne impeccable mais j'ai du mettre require_once 'magpierss-0.61/rss_fetch.inc'; pour moi, sinon ça marchait pas :) !
Solution avec le parser XML de PHP
- avantage: ne necessite pas d'installations supplémentaires
- à peaufiner : code brut, parametre encoding pas encore testé
<?php
/*
Action RSS reader pour wikini
usage: {{rssreader url="http://serveur.tld/url_du_flux_rss"}}
*/
$store = FALSE;
$cur_tag = "";
$cur_data = "";
$cur_item = array('titre'=>'', 'url'=>'', 'contenu'=>'','dat'=>'');
if (!function_exists("startElement")) {
function startElement($parser, $name, $attribs) {
global $cur_tag, $cur_data, $cur_item, $store;
if($name == "ITEM") {
$store = TRUE;
}
$cur_tag = $name;
$cur_data = "";
}
}
if (!function_exists("endElement")) {
function endElement($parser, $name) {
global $cur_item, $store;
if($name == "ITEM") {
echo "";
if($cur_item['dat'] != '') {
$dat = eregi_replace("T"," ",$cur_item['dat']);
}
if($cur_item['contenu'] != '') {
echo "<h3><a href=\"".$cur_item['url']."\">".$cur_item['titre']."</a></h3>";
echo "<p> (" . $dat . ") ". $cur_item['contenu']."</p>\r\n";
} else {
echo "$dat: <a href=\"".$cur_item['url']."\">".$cur_item['titre']."</a><br />\n";
}
$cur_item['titre'] = '';
$cur_item['url'] = '';
$cur_item['contenu'] = '';
$cur_item['dat'] = '';
$store= FALSE;
}
}
}
if (!function_exists("characterData")) {
function characterData ($parser, $data) {
global $cur_tag, $cur_item, $store;
if($store == TRUE) {
if($cur_tag == "TITLE") {
$cur_item['titre'] .= rtrim($data);
}
else if ($cur_tag == "LINK") {
$cur_item['url'] .= rtrim($data);
}
else if($cur_tag == "DESCRIPTION") {
$cur_item['contenu'] .= $data;
}
else if($cur_tag == "DC:DATE") {
$cur_item['dat'] .= $data;
}
}
}
}
$encoding = $this->GetParameter("encoding");
$xml_file = $this->GetParameter("url");
if (empty($encoding)) {
$encoding = "iso-8859-1";
}
if($fp = @fopen($xml_file, "r")) {
echo "<a href=\"$xml_file\">RSS</a><br />";
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, 'startElement','endElement');
xml_set_character_data_handler($xml_parser, 'characterData');
while ($data = fread($fp, 4096)) {
if($encoding == "utf-8") {
$data = utf8_decode($data);
}
xml_parse($xml_parser, $data);
}
fclose($fp);
xml_parser_free ($xml_parser);
}
?>
AJAX
Problème : si le site est lent à donner le flux RSS, la page entière est lente.
Solution : utiliser AJAX avec l'inconvénient d'être inaccessible aux navigateurs ne supportant pas le javascript.
Une implémentation :
actions/rss.php
<?
// Supposition : un même flux RSS est affiché une unique fois dans une même page Wiki.
// paramètre url : URL du flux RSS à afficher.
// paramètre author : afficher ou non le(s) auteur(s) de chaque item.
$id="RSS".md5($this->GetParameter("url", ""));
$author=$this->GetParameter("author", "");
?><div id="<? echo $id ?>"><script type="text/javascript" language="javascript"> showRSS('<? echo urlencode($url) ?>', document.getElementById('<? echo $id ?>')<?
if ($author=="true") {echo ", true"; }
?>); </script></div>
Le javascript à ajouter en entête de la page HTML :
function createXMLHttpRequest() {
var http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
return false;
}
return http_request;
}
function showRSS(url, node, author) {
try {
node.innerHTML = "Chargement en cours...";
var http_request = createXMLHttpRequest();
http_request.onreadystatechange = function() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
node.innerHTML = http_request.responseText;
} else {
node.innerHTML = 'Problème ('+http_request.statusText+')'
}
}
}
if (author) {
author = "&author=true";
} else {
author = "";
}
http_request.open('GET', 'rpc/rss.php?url=' + url + author, true);
http_request.send(null);
}
catch(e) {
document.write('Problème ('+e.message+')');
}
}
Le javascript remplace le contenu du noeud
node par le contenu fournis par la page
rpc/rss.php. Ce fichier peut utiliser les méthodes décrites plus haut.
C'est juste un premier jet. --
AlexandreF
Discussions
Je ne suis pas convaincu à 100% de l'interêt pour
WikiNi de lire des flux RSS, puisque, pour moi, l'interêt majeur d'un flux RSS est de fournir un flux à lire hors web, dans une application spécialisée (comme multiticker sous gnome/linux par exemple), quant à ce qui est de la fourniture d'un flux RSS (sur
DerniersChangements surtout): tout à fait d'accord.
Comme de toute façon, la création d'une action supplémentaire n'impacte pas vraiment le coeur
WikiNi, pas de problème pour voir une telle action se développer. Les lois de la sélection naturelle feront émerger les actions les plus indispensables !
--
DavidDelon
L'émergence de sites comme Netvibes, de pages personnalisables comme Google ou Start de MS te donnent vraisemblablement tord.
J'avais je l'avoue aussi la même approche que toi à cette époque... mais les choses changent.
De plus cela renforce l'aspect communautaire du web montrer ces flux RSS préférés est un peu dans le même esprit que le social bookmarking (del.icio.us)
et toutes ces technologies estampillées Web2.0
Wikini devrait pouvoir devenir une sorte de page personnalisable, personnelle privée ou publique (partageable, modifiable, etc...)
Wikini pourrait ainsi servir de lecteur de fils RSS, de lecteur de podcasts...
Chacun pourrait faire ça sur son propre wiki, mais on pourrait aussi imaginer un hébergement payant ou gratuit mais financé par de la pub
(ça serait un moyen de financer le développement de Wikini)
--
SebCls
Je me permets d'ailleurs de rappeler qu'à l'origine le RSS a été inventé pour la syndication
entre sites et non pour la vision hors ligne.
(pour ce qui est de faire un hébergement gratuit financé par de la pub, je dois dire que je dispose, je pense, des ressources nécessaires sur mon espace d'hébergement, mais je n'ai jamais eu le temps de le faire, bien que j'en ai l'intention depuis longtemps maintenant...)
--
DidierLoiseau