Importer un site existant dans WordPress…
Attention: cet article date du 3 avril 2012
Ce qu'il contient est peut être encore valable...
... ou complètement obsolète!
Actuellement, entre autres occupations, je travaille à la migration d’un site depuis une version développée à la main par moi même il y a quelques temps, vers une version WordPress. Voulant éviter le copié/collé, je planche sur un petits script PHP me permettant l’automatisation.
L’occasion de (re)toucher du doigt la structure interne de ce CMS, et de constater les problèmes…
Une histoire de permaliens, principalement.
Principe de la migration
Il est très simple, quasiment universel à toute migration et suppose une simple boucle.
pour chaque article dans l'ancienne table créer un objet $wppost mettre dedans les données dans les bonnes cases, au bon format insérer dans la table wp_post boucler
Ça, c’est pour la théorie. Bien sûr il faut mettre à jour les éléments liés, comme les tables wp_term_relationships
, ou wp_term_taxonomy
, les images à la une (wp_postmeta
) et autres fantaisies.
Le truc étant de bien connaître le modèle de données (la structure interne des tables) et le fonctionnement des applications, tant de départ que d’arrivée (c’est dans ces cas là aussi que les cahiers des charges et les documents techniques d’une application servent).
Bref, du classique en terme de migration, que je pratique déjà depuis… (ouch)… un certain temps pour passer de Oracle à Oracle nouvelle structure, de dBaseII à Omnis, de Omnis à Access, ou de Access à MySQL…
Et presque à chaque fois, ce qui était clair, précis et sans faille sur le papier, se révèle dans la réalité une usine à gaz ou un mais c’est quoi ce b***l…
Avec WordPress, j’avoue que le schéma est assez clair, et que ça se déroule plutôt pas mal.
Sauf pour les permaliens…
Fonctionnement interne des permaliens
On pourrait penser que, pour optimiser le processus, WordPress crée et stocke dans la table les permaliens selon la règle définie. En fait non.
Quand on crée des articles dans WordPress, il va:
- remplir le champs
post_title
qui sera une version propre du titre, sans espace, sans accents ni caractères spéciaux (tiens, tiens…), correspondant au%postname%
que l’on trouve dans les permaliens - dans le même temps, il crée le guid, correspondant à l’adresse canonique et non permalink du type
http://localhost/?p=136
A chaque appel de la fonction the_permalink()
, il va concaténer les informations selon le format retenu.
Parenthèse référencement
Glissons au passage un petit mot sur l’importance du choix de nos titres (et donc de nos permaliens) qui seront massivement utilisés pour le référencement.
Ces informations seront (généralement et idéalement) exploitées:
- Pour le titre: repris dans la balise <title> de la page (souvent suivi ou précédé du nom du site), pour le fil d’ariane, pour le <h1>…
- Pour le permalien: sera l’adresse de la page (avec l’url du site devant, of course), le lien canonique dans les <metas>…
On trouve partout dans notre thème (liste, archives, moteur de recherche…) des liens :
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
Choisir et travailler titre et permalien est donc crucial (rien n’empêche de changer ce dernier pour introduire des synonymes aux mots du titre).
Permalien = lien unique ?
Si l’on retient le nom de l’article comme structure (menu Réglages > Permaliens):
/%postname%/
Il faut s’assurer que le champs post_title
soit unique (au passage, notez que %postname%
est utilisé dans les permaliens, mais corresponds au champs post_title
de la table wp_posts).
En cas de conflit, WordPress rajoute simplement un numéro derrière:
bonne-annee bonne-annee-2
Bien sûr, si je court-circuite le fonctionnement normal de WordPress avec ma procédure d’import, et que je ne fais pas attention (avant de le savoir, par exemple), j’insère comme un sauvage mes post_name, et me retrouve avec des doublons.
Ayant retenu comme structure de permalien le simple nom de l’article (donc %postname%
) que se passe-t-il si je veux consulter l’article? Deux pages ayant la même adresse ?
Je m’attendais à obtenir une erreur, du genre non trouvé, pensant qu’il allait chercher UN article et qu’en cas de PLUSIEURS il paniquait. Et en fait, je me posais la question depuis longtemps, de savoir comment ça se passerait si…
Mais non. Si votre page single.php
est propre, c’est à dire intégrant la fameuse boucle WordPress, il affichera simplement la liste de tous les articles correspondants.
Un bon moyen de gérer les insertions sauvages (censée ne jamais arriver, je le rappelle).
Régler les conflits ?
Ayant travaillé un peu comme un sauvage, donc, je me suis demandé comme résoudre le problème le plus automatiquement possible, sans y passer trop de temps, sans me prendre la tête, et sans créer un site bancal.
Solution 1: s’obstiner dans le travail de cochon (mais mieux)
Une solution relativement élégante serait de modifier ma procédure d’importation, pour qu’elle vérifie l’unicité des post_title
en ajoutant un numéro manuellement…
Un peu comme le ferait WordPress d’ailleurs.
Cela reste du bricolage.
Solution 2: re-générer les permaliens.
Ceux qui ont suivi me répondront: mais il génère les liens à l’affichage, donc ça sert à rien… Ceux là auront raison. Sauf que j’ai compris ça après avoir tenté cette solution.
Car cela me paraissait une bonne idée: aller dans Réglages > Permaliens, et faire Enregistrer les modifications.
Sauf que, on l’aura compris, les post_title
n’ont pas changé, rien à modifier, problème non résolu.
Solution 3: modifier la structure des permaliens
Là, pour le coup, c’est une solution qui fonctionne. On passe à une nouvelle structure des permaliens, durable, pour y inclure l’ID ou la date de l’article:
/%post_id%-%postname%/
D’ailleurs, intégrer le id (numéro unique par définition) est une solution que je préconise généralement, garantissant l’unicité des permaliens.
Sauf que le cahier des charges avait dit pas de ID dans ce cas. Modifier le cahier des charges?
Solution 4: résoudre manuellement les conflits
Si la quantité n’est pas très importante, c’est une solution fiable.
On fait l’import à la sauvage (propre), puis on va (via l’admin de WordPress) modifier chaque article posant soucis.
Bien sûr, si la quantité d’articles est importante…
Solution 5: utiliser un format d’import connu
Là, on commence à travailler proprement.
WordPress dispose d’un menu Outils > Import, avec différentes procédures possibles, c’est à dire des extensions dédiées à l’import de format précis.
Dont un flux RSS, facile à générer depuis a peu près n’importe quelle base de données, n’importe quelle donnée existante.
D’ailleurs, la plupart (?) des sites dynamiques actuels intègrent un flux RSS, cela permet donc de se simplifier la vie. La plupart… pas tous.
Solution 6: créer une extension d’importation.
Ce serait la meilleure solution bien sûr.
Écrire une extension d’import dédiée à notre format. Intéressant dans le principe. Surtout intéressant si cela doit arriver souvent, pour adapter à chaque cas de figure.
Là encore, schématiquement, si on se penche sur une extension existante (rss-importer.php) on retrouve une boucle qui traite les données, mais qui utilise les fonctions WordPress pour insérer dans la base. Et donc vérifie l’unicité des éléments, entre autres fantaisies.
Cela me tenterait bien… je mets ça dans la to do list des choses à faire à l’occasion. Plutôt à ce moment là, quoi.
Conclusion
Dans le cas d’une prestation réelle ou sérieuse, importer des données dans WordPress se doit d’être fait dans les règles, c’est à dire créer un plugin d’import utilisant les procédures purement WordPress. Ou utiliser un plugin existant (il en exister pour importer d’un certain nombre de CMS open-source).
Dans mon cas précis, comme on parle d’un site qui contient finalement peu d’articles, une solution manuelle (ou en partie manuelle, genre solution 4) peut être retenue, le risque de conflit étant faible, et les mauvaises surprises quasi nul.
A la limite, passer par du copié/collé aurait été aussi rapide que de coder ma procédure d’importation + constater le problème + trouver des solutions + écrire ce récapitulatif. Mais cela aurait été moins formateur.
D’autant qu’il sera sans doute nécessaire de retravailler chaque article un par un pour modifier le format initial au nouveau format, difficile à automatiser à 100%.
Comme d’ailleurs après chaque cas de migration constatée (de ma longue et vieille expérience…), une vérification manuelle est quasiment souvent systématique et indispensable.
Post Scriptum : ceux qui me suivent depuis longtemps (ce blog existe depuis 2003…) se souviendront peut être d’un article intitulé Migration vers WordPress. Je n’avais alors pas été confronté au soucis des permaliens, car ceux-ci intégraient l’ID dès le départ…