Flux RSS de WordPressC’est suite à une demande d’Olivier de WebRankInfo que je me suis penché sur le cas des flux de WP.

Ceux qui suivent SeoMix auront remarqué dans un précédent article mon explication sur la manière de modifier le contenu des flux RSS de WordPress.

Sauf que ces flux possèdent aussi des balises métas invisibles pour les visiteurs, mais qui apparaissent pour d’éventuels moteurs de recherche et autres logiciels d’indexation. La question était alors de savoir comment les modifier.

Les balises XMl des flux WordPress

Olivier souhaitait supprimer les balises XML <Category> de tous les flux RSS de WordPress, sans pour autant modifier les fichiers du CMS situé dans le répertoire wp-includes. Ces balises apparaissent comme ceci dans le code source des « feed » :

< category >< ! [CDATA[Ecommerce]] >
< category >< ! [CDATA[Fails]] >
< category >< ! [CDATA[Webmarketing]] >
< category >< ! [CDATA[Wordpress]] >
...

Ces flux RSS possèdent donc un défaut majeur : ils mélangent catégories et mots clés, mais oublient les taxonomy. Pire encore, ils vont récupérer TOUTES les catégories et mots clés d’un article, ce qui les rend inutiles pour les moteurs de recherche ou pour les agrégateurs de contenus.

En cherchant un peu, j’ai compris que WordPress utilise le fichier feed-rss2.php pour générer son flux RSS par défaut. Ce fichier est un template, c’est à dire un modèle dans lequel WP va injecter ses contenus. Il fait alors appel à deux fonctions pour les balises XML <category> : the_category_rss(), qui fait elle-même appel à get_the_category_rss().

On peut donc influer sur les contenus XML des flux RSS en utilisant un filtre sur la fonction the_category_rss(). Après quelques tests et une ou deux prises de tête, voici les hacks que j’ai réussi à créer :

Supprimer les balises XML des flux RSS

Pour les supprimer purement et simplement, il suffit de copier/coller ce code dans le fichier functions.php de votre thème WordPress :

// Supprimer les balises XML Category des flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrssno');
function xmlrssno($type = null) {$the_list = '';}

Et voilà, le tour est joué : les flux RSS de WordPress ne contiennent plus aucune balises XML Category.

Modifier les balises XML des flux RSS

Il existe d’autres possibilités qui utilisent le même hack. On peut demander à ce que le flux RSS de WordPress utilise uniquement les catégories, les mots ou les taxonomy. On peut également lui demander de ne prendre qu’un mot clé, ou qu’une catégorie pour remplir la balise XML <category>.

Uniquement les mots clés :

// Ne garder que les balises XML Category des mots clés pour les flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsstag');
function xmlrsstag($type = null) {
  if ( empty($type) ) $type = get_default_feed();
	$tags = get_the_tags();
  $thelist = '';
	$cat_names = array();
	$filter = 'rss';
	if ( 'atom' == $type ) $filter = 'raw';
	if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
    $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);}
	$cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Un seul mot clé :

// Ne garder qu'une balises XML Category de mots clés pour les flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsstagun');
function xmlrsstagun($type = null) {
  if ( empty($type) ) $type = get_default_feed();
	$tags = get_the_tags();
  $thelist = '';
	$cat_names = array();
	$filter = 'rss';
	if ( 'atom' == $type ) $filter = 'raw';
	if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
    $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);}
	$cat_names = array($cat_names[0]);$cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Plusieurs mots clé :

Pensez à remplacer la valeur de $count par le nombre de mots clés que vous voulez utiliser dans le XML de votre flux RSS WordPress :

// Ne garder qu'un nombre défini de balises XML Category de mots clés pour les flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsstagseveral');
function xmlrsstagseveral($type = null) {
  if ( empty($type) ) $type = get_default_feed();
	$count=7;
  $tags = get_the_tags();
  $thelist = '';
	$cat_names = array();
	$filter = 'rss';
	$tags = array_slice($tags, 0, $count);
  if ( 'atom' == $type ) $filter = 'raw';
  if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
    $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);}
  $cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Uniquement les catégories :

// Ne garder que les balises XML Category des catégories pour les flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsscategory');
function xmlrsscategory($type = null) {
	if ( empty($type) )$type = get_default_feed();
	$categories = get_the_category();
	$thelist = '';
	$cat_names = array();
	$filter = 'rss';
	if ( 'atom' == $type )
		$filter = 'raw';
	if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
    $cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);}
	$cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Une seule catégorie :

// Ne garder qu'une balises XML Category de catégorie pour les flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsscategoryun');
function xmlrsscategoryun($type = null) {
	if ( empty($type) )$type = get_default_feed();
	$categories = get_the_category();
	$thelist = '';
	$cat_names = array();
	$filter = 'rss';
	if ( 'atom' == $type )
		$filter = 'raw';
	if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
    $cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);}
  $cat_names = array($cat_names[0]);$cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Une taxonomie :

Pour rappel, une taxonomie sur WordPress correspond à une nouvelle hiérarchisation de vos contenus. Par défaut, vos articles sont classés par catégorie et mots clés. Mais vous pouvez très bien créer un nouveau type de catégorisation, que l’on appelle les taxonomies.

On peut donc utiliser ces informations pour la balise XML de vos flux RSS WordPress. Remplacez dans ce code « XXXXXX » par le nom de votre taxonomy, puis copier/coller le tout dans votre fichier functions.php.

// Utiliser une taxonomy pour la balise XML Category des flux RSS - Code par www.seomix.fr
add_filter('the_category_rss', 'xmlrsstaxo');
function xmlrsstaxo($type = null) {
  if ( empty($type) ) $type = get_default_feed();
	global $post;
  $mytaxonomy = get_the_terms($post->ID, 'XXXXXX');
  $thelist = '';
	$cat_names = array();
	$filter = 'rss';
	if ( 'atom' == $type ) $filter = 'raw';
	if ( !empty($mytaxonomy) ) foreach ( (array) $mytaxonomy as $tag ) {
    $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, $mytaxonomy, $filter);}
	$cat_names = array($cat_names[0]);$cat_names = array_unique($cat_names);
	foreach ( $cat_names as $cat_name ) {
		if ( 'rdf' == $type )
			$thelist .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
		elseif ( 'atom' == $type )
			$thelist .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
		else
			$thelist .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";}
  return $thelist;}

Et voilà. Vous n’avez maintenant plus qu’à choisir parmi les codes précédents le hack WordPress qui correspond le mieux à vos besoins. Pour ma part, je vous conseille l’utilisation du hack avec une seule catégorie, ou celui avec la taxonomy. C’est ce qui sera le plus pertinent pour votre flux RSS vis-à-vis des moteurs de recherche et agrégateurs.

Comme on dit, c’est fou ce que l’on peut faire avec WordPress 3 ;)