Contenu principal

WordPress MU et le blog imposé dans l’url

Si vous avez un WordPress MU, vous vous êtes sûrement rendu compte de l’apparition d’un niveau « /blog » dans l’url de vos articles du site principal.
Voici comment modifier ou supprimer ce niveau.

NOTA : par abus de langage je parle de « WordPress MU », mais il s’agit de la fonction réseau introduite par WordPress 3.

[update] 21-02-2013
Bon, sans déconner, il y a plus de deux ans, je racontais pas mal de conneries quand même (ça m’arrive encore parfois, rassurez-vous). Le conseil du jour : pas de flush_rules() à l’init, à chaque fois c’est un lourd enregistrement en base de donnée, ça coute cher. Solution alternative : j’ai découvert cet article chez l’ami WPChannel. Je n’ai pas personnellement testé son astuce mais cela semble fonctionner (du moins elle marchait encore en avril 2012 ^^), et c’est beaucoup plus économe en ressources :)

Pour la petite histoire

Depuis quelques jours je m’essaye à WordPress MU sur un site de test. Le système est assez sympa et diffère légèrement d’un WordPress classique. Mais, quelle ne fût pas ma surprise en voyant un 404 apparaitre sur mes articles (WTF!?). Petit tour direct dans l’onglet Permaliens, je remarque le « /blog » apparu devant les champs texte (WTF!?x2) et je met à jour. Retour en front-end, rafraichissement, plus de 404 o/. Mais là, ce « blog » apparait dans l’url (WTF!?x3).
Après un petit tour dans un fichier core de WP, il s’avère que ce « /blog » est « hard codé » et imposé au blog principal si l’on a choisi de faire son réseau avec des « niveaux » dans l’url au lieu d’utiliser des sous-domaines (Quoi?! o_O ). Quelques recherches sur le net plus tard, je ne suis pas le seul à vouloir me débarrasser de cet indésirable, et tout ce que j’ai à me mettre sous la dent est un vieux rapport de « bug » dont la solution consiste à modifier 2 fichiers core.
Bien sûr, tout ceci ne me plait pas du tout et j’ai, à priori, mieux à proposer avec un hack.

Modifier ou supprimer l’étage indésirable

Pour cela nous allons utiliser la classe WP_Rewrite de WordPress pour réécrire la structure de permalien après son enregistrement dans les réglages.
Méthode : créer un hook à l’initialisation qui va :

  • vérifier que l’on est bien sur le blog principal d’un multisite,
  • récupérer la structure de permalien enregistrée,
  • rechercher la chaine « /blog/ »,
  • si la chaine est trouvée au début du permalien, elle est remplacée par ce que l’on veut,
  • réinjecter la nouvelle structure,
  • mettre à jour le tout (enfin, un coup de flush quoi).

A mettre dans le fichier functions.php de votre thème :

0102030405060708091011

function get_rid_of_blog_rewrite_rule() {
	global $wp_rewrite;
	$permalink_structure = $wp_rewrite->permalink_structure;
	if (strpos($permalink_structure, '/blog/') === 0) {
		$wp_rewrite->set_permalink_structure( str_replace('/blog/', '/', $permalink_structure) );
		$wp_rewrite->flush_rules();
	}
}
global $current_blog;
if ( is_multisite() && isset($current_blog) && $current_blog->blog_id == 1 )
	add_action('init', 'get_rid_of_blog_rewrite_rule');

Avec la condition if ( is_multisite() && isset($current_blog) && $current_blog->blog_id == 1 ) on vérifie que nous sommes bien sur le blog principal d’un multisite, afin de ne pas impacter les autres blogs.
Ensuite c’est la variable globale $wp_rewrite qui nous donne accès à la classe WP_Rewrite de WordPress.
$wp_rewrite->permalink_structure permet de récupérer la structure de permalien sous forme de chaine (« /blog/%postname%-%post_id%/ » par exemple).
Avec strpos($permalink_structure, '/blog/') === 0 nous vérifions si la chaine « /blog/ » se trouve au début de la structure. Deux choses importantes : les deux « / » autour de « blog », c’est pour éviter de créer une erreur avec par exemple « /blogosphere/le-nouveau-blog-de-toto », qui deviendrait « /osphere/le-nouveau–de-toto ». Le second point est le « === » qui est très important, car si « /blog/ » n’est pas trouvé, strpos renverra false, qui est équivalent à 0 (mais pas strictement égal à 0), et donc la suite sera lancée inutilement.
$wp_rewrite->set_permalink_structure( ) permet d’enregistrer la nouvelle structure.
Remarque : avec str_replace('/blog/', '/', $permalink_structure) on va carrément supprimer le niveau « /blog ». Si vous préférez seulement le remplacer par « /news », alors nous aurons str_replace('/blog/', '/news/', $permalink_structure).
Dernier point, et pas des moindres : $wp_rewrite->flush_rules(); sans quoi la structure ne sera pas mise à jour.

See ya!

NOTA : si vous faites cette opération sur un blog existant, n’oubliez pas le paquet de redirections 301 qui va avec.