Vous voulez créer votre propre flux RSS de news pour votre site ? Vous voulez utiliser une librairie (lib) XML pour avoir un code plus joli, plus propre, mais vous ne trouvez aucun tutoriel à ce sujet sur Google ?
Pour commencer, nous allons aborder les bases qui me semblent nécessaires pour comprendre la suite du tuto, et surtout examiner le fonctionnement de la lib XML. Elle n'est vraiment pas difficile à comprendre (c'est bien pour cela que je l'utilise :-° ), mais sans quelques mots de vocabulaire, vous aurez du mal à voir de quoi je parle.
Prenons par exemple un fichier XML « au hasard » (bon, pas vraiment au hasard : il nous servira encore par la suite).
<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
<channel>
<description>Une description</description>
<link>Un lien</link>
<title>Oh, un titre ! :D</title>
</channel>
</rss>
<channel> est ce que l'on appelle une balise. Comme vous le savez, les balises vont par « paires », c'est-à-dire qu'il y a une balise ouvrante et une balise fermante. Dans cet exemple avec <channel>, la balise ouvrante est <channel> et la balise fermante </channel>. Il y a aussi les balises autofermantes comme <img />, mais elles ne nous intéressent pas dans cet article. Une balise peut en outre prendre un (ou plusieurs) arguments ; par exemple, version est un argument de la balise <rss> qui a pour valeur 2.0.
Quelques mots concernant la lib que nous utiliserons pour parser le fichier XML afin de créer notre flux RSS : il s'agira de DomXML pour PHP4. Pour la documentation officielle, c'est par ici. Avec cette documentation et un peu de logique, vous pouvez faire énormément de choses. ;)
À présent, parlons un peu vocabulaire : voici quelques informations qui vous aideront à comprendre le nom des fonctions de DomXML. ^^ Dans notre fichier XML, la balise <channel> est aussi appelée « node » (« nœud », en français). Elle fait partie d'un node root (nœud parent), ici <rss>. On dit aussi que <channel> est une balise fille ou un fils (child) de <rss>. Si vous avez bien compris cela, vous avez sans doute déduit que les balises <description>, <link> et <title> sont des enfants de <channel>.
En résumé, on a :
<channel>, appelée « node » dans la lib XML. C'est le node root de <description> ;
Après avoir vu un peu de vocabulaire utile à la compréhension du tutoriel, nous allons nous intéresser à la structure que devra respecter le fichier XML pour être lisible par un lecteur de flux RSS. Prenons pour exemple le Site du Zéro. :-°
Voici la structure du début du fichier.
<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
<channel>
<description>Description du site</description>
<link>Lien vers le site</link>
<title>Titre du site</title>
</channel>
</rss>
C'est la base d'un fichier XML pouvant être lu par un lecteur de flux RSS. Bien sûr, vous pouvez ajouter des éléments.
À présent, étudions la structure d'un élément (dans notre cas, une news) qui est à mettre entre les balises <channel></channel> du fichier XML vu précédemment. ;)
<item>
<title>Titre de la news</title>
<link>Lien vers la news en entier</link>
<description>Description de la news, le mieux étant de mettre le contenu de la news</description>
<comments>Un lien vers des commentaires de news</comments>
<author>Auteur de la news</author>
<pubDate>Date de publication de la news</pubDate>
<guid>Texte qui identifie de manière unique la news, le mieux étant de mettre le titre de la news</guid>
<source>Source dont est tirée la news</source>
</item>
Quelques explications s’imposent. Le nœud item va correspondre à une news dans la liste des news du fichier XML, c'est-à-dire qu'une fois votre fichier XML construit, vous aurez sans doute quelque chose ressemblant à ceci :
<item>
<!-- Titre, lien, etc. de la première news -->
</item>
<item>
<!-- Titre, lien, etc. de la deuxième news -->
</item>
<item>
<!-- etc. -->
</item>
Voilà, cette structure vous permettra d'obtenir un flux RSS assez complet ; bien sûr, vous pouvez ajouter encore plus de choses. ;)
Une fois que l'on connaît la manière dont doit être construit le document XML, il est temps de savoir comment récupérer le contenu qu'il faut y insérer. :D
Tout d'abord, jetons un œil à la structure de la table news servant de modèle pour ce tuto.
CREATE TABLE `news` (
`nws_id` smallint(3) UNSIGNED NOT NULL AUTO_INCREMENT,
`nws_pseudo` varchar(255) NOT NULL DEFAULT '0',
`nws_titre` varchar(255) NOT NULL DEFAULT '',
`nws_contenu` text NOT NULL,
`nws_date` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY `id` (`nws_id`),
) TYPE=InnoDB COMMENT='Contient les news' AUTO_INCREMENT=59 ;
Cette table n'a rien d'exceptionnel ; si vous ne la comprenez pas, c’est que vous n'avez pas suivi les cours de M@teo correctement. :-°
Intéressons-nous à la requête destinée à sélectionner les différents éléments.
SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news ORDER BY nws_date DESC LIMIT 10 OFFSET 0
Maintenant, il ne nous reste plus qu'à envoyer la requête au serveur MySQL.
<?php
mysql_connect("localhost", "root", "mdp");
mysql_select_db("nom_bdd");
$nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
?>
Ici, on sélectionne les dix dernières news. Libre à vous de modifier cette valeur. Et voilà. Ces quelques lignes de code ne devraient pas vous surprendre si vous avez lu le tuto depuis le début. :)
Il ne vous reste plus qu'à vous souvenir que $nws contient la liste des news que vous voulez mettre dans votre flux RSS.
Nous sommes presque arrivés au bout de nos peines. Plus que quelques minutes d'attention et vous aurez enfin votre flux RSS. ^^
Voici la ligne de code permettant d'initialiser le fichier XML :
<?php
$xml_file = domxml_new_doc("1.0");
?>
Cette ligne crée simplement un fichier XML temporaire en mémoire dans lequel on indique la version XML utilisée (ici : version 1.0).
À présent, voyons comment créer le nœud maître rss puis un nœud fils channel.
<?php
function &init_news_rss(&$xml_file)
{
$root = $xml_file->create_element("rss"); // création de l'élément
$root->set_attribute("version", "2.0"); // on lui ajoute un attribut
$root = $xml_file->append_child($root); // on l'insère dans le nœud parent (ici root, qui est "rss")
$channel = $xml_file->create_element("channel");
$channel = $root->append_child($channel);
$desc = $xml_file->create_element("description");
$desc = $channel->append_child($desc);
$text_desc = $xml_file->create_text_node("Partage de connaissances en tous genres"); // on insère du texte entre les balises <description></description>
$text_desc = $desc->append_child($text_desc);
$link = $xml_file->create_element("link");
$link = $channel->append_child($link);
$text_link = $xml_file->create_text_node("http://www.bougiemind.info");
$text_link = $link->append_child($text_link);
$title = $xml_file->create_element("title");
$title = $channel->append_child($title);
$text_title = $xml_file->create_text_node("Bougie'S mind");
$text_title = $title->append_child($text_title);
return $channel;
}
?>
Cette fonction retourne une référence : ainsi n'obtient-on pas une simple copie de l'élément, mais bien l'élément lui-même. ;)
À présent, vous avez un fichier XML (toujours en mémoire) qui devrait ressembler à ceci :
<?xml version="1.0" encoding="ISO-8859-15" ?>
<rss version="2.0">
<channel>
<description>Partage de connaissances en tous genres</description>
<link>http://www.bougiemind.info</link>
<title>Bougie'S mind</title>
</channel>
</rss>
Maintenant, nous allons passer à la partie la plus difficile à comprendre (je vous rassure, elle est quand même tout à fait abordable) : la création des items (chaque item correspond à une news différente). La fonction prend comme arguments :
Normalement, aucune de ces fonctions ne vous est inconnue : elles ont été décrites plus haut. ;)
Voici à quoi ressemble le bout de fichier XML que vous venez de créer.
<item>
<title>Flux RSS des news en place</title>
<link>http://www.bougiemind.info/rss_news56.html</link>
<description>Voilà, le flux RSS des news est en place !</description>
<comments>http://www.bougiemind.info/news-11-56.html</comments>
<author>Bougie</author>
<pubDate>24/04/2006 12:42</pubDate>
<guid>http://www.bougiemind.info/rss_news56.html</guid>
<source>http://www.bougiemind.info</source>
</item>
Il ne nous reste plus qu'à élaborer une boucle sur la fonction add_news_node afin de créer un élément item à chaque fois qu'il y a une news. Je vous laisse réfléchir. ;)
…
Vous avez réfléchi ? Bon, je ne vous fais pas patienter plus longtemps. ^^
Maintenant que l'on a vu comment faire un flux RSS, on va essayer de mettre un peu d'ordre dans ce code qui, pour le moment, est assez brouillon : on va tout regrouper dans un fichier flux_rss.php.
Nous allons également créer une fonction qui s'occupera de mettre à jour le flux RSS :
<?php
function rebuild_rss()
{
// on se connecte à la BDD
mysql_connect("localhost", "root", "mdp");
mysql_select_db("votre_table");
// on récupère les news
$nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
// on crée le fichier XML
$xml_file = domxml_new_doc("1.0");
// on ajoute chaque news au fichier RSS
while($news = mysql_fetch_assoc($nws))
{
add_news_node($xml_file, $channel, $news["nws_id"], $news["nws_pseudo"], $news["nws_titre"], $news["nws_contenu"], date("d/m/Y H:i", $news["nws_date"]));
}
// on écrit le fichier
$xml_file->dump_file("news_FR_flux.xml");
}
?>
Vous avez maintenant une fonction qui reconstruira votre flux RSS à chaque fois que vous l'appellerez. ;)
Si on récapitule, vous devriez avoir un fichier flux_rss.php comme celui-ci :
<?php
function &init_news_rss(&$xml_file)
{
$root = $xml_file->create_element("rss"); // création de l'élément
$root->set_attribute("version", "2.0"); // on lui ajoute un attribut
$root = $xml_file->append_child($root); // on l'insère dans le nœud parent (ici root qui est "rss")
$channel = $xml_file->create_element("channel");
$channel = $root->append_child($channel);
$desc = $xml_file->create_element("description");
$desc = $channel->append_child($desc);
$text_desc = $xml_file->create_text_node("Partage de connaissances en tous genres"); // on insère du texte entre les balises <description></description>
$text_desc = $desc->append_child($text_desc);
$link = $xml_file->create_element("link");
$link = $channel->append_child($link);
$text_link = $xml_file->create_text_node("http://www.bougiemind.info");
$text_link = $link->append_child($text_link);
$title = $xml_file->create_element("title");
$title = $channel->append_child($title);
$text_title = $xml_file->create_text_node("Bougie'S mind");
$text_title = $title->append_child($text_title);
return $channel;
}
function add_news_node(&$parent, $root, $id, $pseudo, $titre, $contenu, $date)
{
$item = $parent->create_element("item");
$item = $root->append_child($item);
$title = $parent->create_element("title");
$title = $item->append_child($title);
$text_title = $parent->create_text_node($titre);
$text_title = $title->append_child($text_title);
$link = $parent->create_element("link");
$link = $item->append_child($link);
$text_link = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
$text_link = $link->append_child($text_link);
$desc = $parent->create_element("description");
$desc = $item->append_child($desc);
$text_desc = $parent->create_text_node($contenu);
$text_desc = $desc->append_child($text_desc);
$com = $parent->create_element("comments");
$com = $item->append_child($com);
$text_com = $parent->create_text_node("http://www.bougiemind.info/news-11-".$id.".html");
$text_com = $com->append_child($text_com);
$author = $parent->create_element("author");
$author = $item->append_child($author);
$text_author = $parent->create_text_node($pseudo);
$text_author = $author->append_child($text_author);
$pubdate = $parent->create_element("pubDate");
$pubdate = $item->append_child($pubdate);
$text_date = $parent->create_text_node($date);
$text_date = $pubdate->append_child($text_date);
$guid = $parent->create_element("guid");
$guid = $item->append_child($guid);
$text_guid = $parent->create_text_node("http://www.bougiemind.info/rss_news".$id.".html");
$text_guid = $guid->append_child($text_guid);
$src = $parent->create_element("source");
$src = $item->append_child($src);
$text_src = $parent->create_text_node("http://www.bougiemind.info");
$text_src = $src->append_child($text_src);
}
function rebuild_rss()
{
// on se connecte à la BDD
mysql_connect("localhost", "root", "mdp");
mysql_select_db("votre_table");
// on récupère les news
$nws = mysql_query("SELECT nws_id, nws_pseudo, nws_titre, nws_contenu, nws_date FROM news WHERE ORDER BY nws_date DESC LIMIT 0 OFFSET 10");
// on crée le fichier XML
$xml_file = domxml_new_doc("1.0");
// on initialise le fichier XML pour le flux RSS
$channel = init_news_rss($xml_file);
// on ajoute chaque news au fichier RSS
while($news = mysql_fetch_assoc($nws))
{
add_news_node($xml_file, $channel, $news["nws_id"], $news["nws_pseudo"], $news["nws_titre"], $news["nws_contenu"], date("d/m/Y H:i", $news["nws_date"]));
}
// on écrit le fichier
$xml_file->dump_file("news_FR_flux.xml");
}
?>
Et voilà le travail ! Il vous suffit à présent d'ajouter deux lignes de code pour que votre flux RSS soit reconstruit :
<?php
require('flux_rss.php');
rebuild_rss();
?>
Il ne vous reste plus qu'à indiquer au navigateur que votre site possède un flux RSS, et pour cela une simple ligne en XHTML suffit.
<link rel="alternate" type="application/rss+xml" title="{Titre du flux RSS}" href="{Lien vers le flux RSS}" />
{Titre du flux RSS} et {Lien vers le flux RSS} sont bien sûr à remplacer par ce que vous voulez. :)
Vous avez désormais un code qui fonctionnera sur un serveur avec PHP5 ! Et n'oubliez pas : tout ce que je vous ai dit ici, je l'ai trouvé dans la documentation. ;)
Vous devriez maintenant être capables de coder votre propre flux RSS des news de votre site en vous servant d'une lib XML. Merci de m'avoir lu, et à bientôt pour de nouvelles aventures. :-°
P.-S. — À ceux qui souhaitent finaliser le tuto en ajoutant ce qui a été dit dans les commentaires, envoyez-moi un MP. ;)