Le WordPress d'aujourd'hui, décodé pour les développeurs

Outils & workflow

Convertir un site Joomla en WordPress : le script qu’on a fini par écrire

Reprendre un site vitrine Joomla 3 sans plugin d'import générique : un script PHP qui rejoue chaque article et chaque image depuis la base source.

Par WordPress Développement • 7 février 2020 • 5 min de lecture • Aucun commentaire
Convertir un site Joomla en WordPress : le script qu'on a fini par écrire

SELECT id, title, introtext, fulltext, catid, images FROM jos_content WHERE state = 1; : cette requête, lancée directement sur la base Joomla, donne accès à l’essentiel d’un site vitrine sans passer par l’interface d’administration. C’est le point de départ du script qui a servi à reprendre un site Joomla 3.9 pour un client dont l’agence d’origine avait disparu, sans documentation ni export propre.

Les extensions génériques d’import Joomla vers WordPress existent, mais elles s’appuient sur un export XML qui échoue régulièrement dès qu’un article contient du HTML mal formé ou des modules imbriqués. Plutôt que de déboguer un format d’échange tiers, il a semblé plus rapide d’écrire un script PHP autonome qui lit la base Joomla en lecture seule et recrée le contenu via les fonctions natives de WordPress.

Comprendre le schéma Joomla avant d’écrire une ligne de code

Un site Joomla classique en version 3.x stocke ses articles dans la table jos_content (le préfixe varie selon l’installation). Les champs utiles sont title, alias, introtext (le chapô), fulltext (la suite de l’article), catid (la catégorie), created et images, une colonne JSON qui référence l’image mise en avant et une image intro. Les catégories vivent dans jos_categories, avec un champ title et un id qui fait le lien avec catid.

Avant d’écrire le script, un export complet de la base Joomla dans un environnement local isolé s’impose, pour ne jamais interroger la base de production pendant la migration. Une connexion mysqli distincte de wpdb permet de lire cette base source sans toucher à la base WordPress cible.

Rejouer les articles avec les fonctions natives de WordPress

Le script tourne comme une commande WP-CLI personnalisée, ce qui donne accès à wp_insert_post(), wp_insert_attachment() et wp_generate_attachment_metadata() sans réinventer la logique d’insertion. Pour chaque ligne de jos_content, le contenu Joomla ( fulltext concaténé à introtext) passe par un nettoyage minimal des balises obsolètes avant d’être injecté dans post_content.

L'essentiel à retenir : Lecture directe des tables Joomla via mysqli ; Réutilisation des images sans passer par un export XML ; Script relançable sans doublonner les articles
foreach ( $joomla_articles as $article ) {
    $existing = get_posts( array(
        'meta_key'   => '_joomla_id',
        'meta_value' => $article['id'],
        'post_type'  => 'post',
        'numberposts' => 1,
    ) );

    if ( ! empty( $existing ) ) {
        continue; // déjà migré, on ne recrée pas de doublon
    }

    $post_id = wp_insert_post( array(
        'post_title'   => $article['title'],
        'post_content' => nettoyer_contenu_joomla( $article['fulltext'] ),
        'post_excerpt' => wp_strip_all_tags( $article['introtext'] ),
        'post_status'  => 'publish',
        'post_date'    => $article['created'],
    ) );

    update_post_meta( $post_id, '_joomla_id', $article['id'] );
}

Le champ _joomla_id enregistré en meta est ce qui rend le script relançable : en cas d’interruption au bout de 400 articles sur 1 100, on peut le relancer sans créer de doublons, la vérification get_posts() filtrant les articles déjà traités.

Récupérer les images sans export XML

La colonne images de Joomla contient un JSON du type {"image_intro":"images/actus/photo.jpg", ...}. Le chemin est relatif au dossier images/ de l’installation Joomla, qu’il suffit de copier tel quel sur le nouveau serveur avant migration. Le script décode ce JSON avec json_decode(), vérifie l’existence physique du fichier, puis utilise wp_upload_bits() pour copier le binaire dans la structure de médiathèque WordPress avant de créer la pièce jointe avec wp_insert_attachment() et set_post_thumbnail().

  • Lecture du JSON images pour isoler le chemin de l’image intro
  • Copie physique du fichier vers wp-content/uploads via wp_upload_bits()
  • Génération des métadonnées avec wp_generate_attachment_metadata()
  • Association à l’article via set_post_thumbnail()

Les catégories, un mappage à faire à la main

Les catégories Joomla ne correspondent presque jamais telles quelles à une taxonomie WordPress cohérente : elles reflètent souvent l’arborescence du menu plutôt qu’une logique de contenu. Un tableau de correspondance catid Joomla vers term_id WordPress, construit à la main après une relecture des dix ou vingt catégories du site, évite de reproduire une architecture bancale. La fonction wp_set_post_terms() applique ensuite ce mappage lors de l’insertion.

Ne jamais migrer la structure de menu telle quelle : elle a souvent été pensée pour un back-office Joomla, pas pour une taxonomie WordPress claire.

Ce que ce script ne traite pas

Les modules Joomla (blocs latéraux, bannières, mini-formulaires) n’ont pas d’équivalent direct dans ce script : ils demandent une analyse séparée, gabarit par gabarit, pour décider s’ils deviennent des widgets, des blocs ou du contenu en dur dans le thème. Mélanger cette conversion avec la migration du contenu éditorial aurait rendu le script beaucoup plus fragile, pour un gain de temps limité sur un site qui n’avait que trois modules actifs.

En résumé

Un script PHP de quelques dizaines de lignes, exécuté en commande WP-CLI, a suffi pour rejouer plus d’un millier d’articles Joomla vers WordPress sans jamais passer par un format d’export intermédiaire. La clé de la fiabilité tient à deux détails simples : un identifiant Joomla conservé en meta pour rendre le script relançable, et un mappage de catégories construit à la main plutôt qu’automatisé. Pour un site vitrine de taille modeste, cette approche reste plus rapide à déboguer qu’un plugin d’import généraliste.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi