Compétence de thème (Build Theme)
Sélectionne, installe et active un thème Full Site Editing (FSE) à partir de WP.org en fonction de la description en langage naturel du site par l'utilisateur. Cette compétence interroge l'API Thèmes WP.org v1.2 pour les thèmes FSE, évalue les résultats par rapport au prompt NL en utilisant le jugement contextuel de Claude, et installe le meilleur candidat. Une liste de repli organisée garantit une sélection de thème lorsque l'API renvoie des résultats médiocres ou est indisponible.
Séquencement critique : Cette compétence s'exécute APRÈS build-mcp Section 2 (adaptateur MCP activé, base de données réexportée) et AVANT build-content (l'ensemencement du contenu nécessite que le thème soit actif pour la découverte des emplacements de menus).
Cette compétence s'attend à ce que les variables suivantes soient déjà définies par la commande appelante :
BUILD_DIR— chemin absolu vers le répertoire de construction (défini par build-scaffold Section 2)WP— le préfixe de commande WP-CLI (par exemplewp --path=$BUILD_DIRou l'équivalent Docker, défini par build-scaffold Section 4)NL_PROMPT— la chaîne de description du site en langage naturel de l'utilisateurSITE_TITLE— titre du site dérivé du prompt NL (défini par la commande appelante avant cette compétence)
Section 1 : Interrogation de l'API Thèmes WP.org
Interrogez l'API Thèmes WP.org v1.2 pour obtenir le pool de thèmes FSE. Utilisez le tag full-site-editing pour filtrer — c'est le signal public canonique pour les thèmes FSE/block. NE COMBINEZ PAS les paramètres search et tag : l'API ignore les tags lorsque search est présent. Claude évalue la pertinence des thèmes en contexte après avoir récupéré le pool.
echo "[Build] Interrogation de l'API Thèmes WP.org pour le pool de thèmes FSE..."
# ANTI-PATTERN CRITIQUE : N'utilisez PAS ?action=query_themes&request[search]=...&request[tag][]=full-site-editing
# L'API ignore tag[] lorsque search est présent. Utilisez une requête avec uniquement le tag ; Claude évalue la pertinence en contexte.
FSE_THEMES_FILE="/tmp/fse_themes_$$.json"
curl -s --max-time 10 \
"https://api.wordpress.org/themes/info/1.2/?action=query_themes&request[tag][]=full-site-editing&request[browse]=popular&request[per_page]=50&request[fields][active_installs]=true&request[fields][rating]=true&request[fields][description]=true&request[fields][tags]=true" \
-o "$FSE_THEMES_FILE"
CURL_EXIT=$?
# Valider la réponse — vérifier le code de sortie, un fichier non vide et la structure JSON
API_AVAILABLE=false
if [ $CURL_EXIT -eq 0 ] && [ -s "$FSE_THEMES_FILE" ]; then
# Compter les thèmes dans la réponse — au moins 3 pour que Claude évalue correctement
THEME_COUNT=$(python3 -c "import json,sys; d=json.load(open(sys.argv[1])); print(len(d.get('themes', [])))" "$FSE_THEMES_FILE" 2>/dev/null || echo "0")
if [ "$THEME_COUNT" -ge 3 ]; then
API_AVAILABLE=true
echo "[Build] L'API WP.org a renvoyé $THEME_COUNT thèmes FSE pour évaluation."
else
echo "[Build] L'API WP.org a renvoyé moins de 3 thèmes ($THEME_COUNT). Utilisation de la liste de repli organisée."
fi
else
echo "[Build] API WP.org indisponible — utilisation de la liste de thèmes organisée"
fi
Section 2 : Évaluation et sélection du thème
Claude lit la réponse JSON de l'API et évalue chaque thème par rapport au NL_PROMPT. Si l'API a renvoyé un pool viable, Claude sélectionne le meilleur candidat en utilisant la pertinence, la popularité et la note. Si l'API a échoué ou a renvoyé trop peu de résultats, Claude sélectionne dans la liste de repli organisée en fonction de la catégorie du site dans NL_PROMPT.
Critères de notation (par ordre de priorité) :
- Pertinence du nom, de la description et des tags par rapport au type de site décrit dans
NL_PROMPT active_installs— signal de popularité (plus élevé = mieux)rating— signal de qualité (plus élevé = mieux)
Les thèmes classiques ne sont jamais sélectionnés, même s'ils obtiendraient un score plus élevé sur d'autres critères.
if [ "$API_AVAILABLE" = "true" ]; then
echo "[Build] Évaluation des thèmes FSE par rapport au prompt NL : \"$NL_PROMPT\""
echo "[Build] Lecture des thèmes depuis : $FSE_THEMES_FILE"
# Claude lit le JSON des thèmes FSE et évalue chaque thème :
# - themes[].name: nom d'affichage
# - themes[].slug: slug d'installation WP.org
# - themes[].description: description du thème
# - themes[].tags: tags de fonctionnalités/catégories du thème
# - themes[].active_installs: popularité (nombre d'installations actives)
# - themes[].rating: note de qualité (échelle 0-100)
#
# Claude sélectionne le thème avec la meilleure combinaison de :
# (1) pertinence par rapport au type de site du NL_PROMPT
# (2) active_installs élevé
# (3) note élevée
#
# Comportement en cas d'absence de correspondance : si aucun thème n'obtient un bon score par rapport au type de site du NL_PROMPT,
# Claude présente les 3 meilleurs candidats à l'utilisateur et lui demande de choisir.
# Cela interrompt intentionnellement le flux autonome — la satisfaction est plus importante que l'automatisation.
#
# Après la sélection, Claude définit :
THEME_SLUG="<slug sélectionné par Claude à partir des résultats de l'API>"
THEME_NAME="<nom d'affichage sélectionné par Claude à partir des résultats de l'API>"
else
# Liste de repli organisée — associe les catégories de sites à des slugs de thèmes FSE connus
# Ces thèmes sont des thèmes FSE vérifiés et maintenus sur WP.org.
# Mettez à jour cette liste si un thème est supprimé de WP.org.
#
# Catégorie → Correspondance de slug (Claude extrait la catégorie du site du NL_PROMPT) :
#
# portfolio / photographie / création → flavor
# entreprise / corporate / agence → flavor
# blog / magazine / actualités → flavor
# restaurant / nourriture / café → flavor
# ecommerce / boutique / magasin → flavor
# défaut (tout autre) → twentytwentyfour
#
# twentytwentyfour est le repli de dernier recours garanti (maintenu par l'équipe principale de WordPress.org).
#
# Claude lit NL_PROMPT, détermine la catégorie du site et définit :
THEME_SLUG="<slug sélectionné par Claude à partir de la liste de repli organisée>"
THEME_NAME="<nom d'affichage pour le thème de repli sélectionné>"
fi
echo "[Build] Thème sélectionné : $THEME_NAME ($THEME_SLUG)"
Section 3 : Installation et activation du thème
Installez et activez le thème sélectionné à l'aide de WP-CLI. Si l'installation échoue, essayez les candidats de repli. Validez toujours la compatibilité FSE en vérifiant la présence de theme.json après l'installation. Utilisez avertir-et-continuer — n'arrêtez jamais la construction pour des échecs de thème.
echo "[Build] Installation du thème : $THEME_SLUG..."
install_theme() {
local slug="$1"
if $WP theme install "$slug" --activate 2>&1; then
echo "[Build] Thème installé et activé : $slug"
# Validation FSE — vérifier la présence de theme.json
# Claude a sélectionné depuis le pool FSE, c'est donc une confirmation secondaire.
# Un faux négatif est possible si theme.json se trouve dans un sous-répertoire ou est nommé différemment.
if [ -f "$BUILD_DIR/wp-content/themes/$slug/theme.json" ]; then
echo "[Build] FSE validé : theme.json trouvé."
else
echo "[Build] ATTENTION : theme.json non trouvé — le thème n'est peut-être pas compatible FSE."
echo "[Build] Poursuite — Claude a sélectionné ce thème depuis le pool de tags full-site-editing."
fi
# Obtenir la version du thème
THEME_VERSION=$($WP theme get "$slug" --field=version 2>/dev/null || \
grep -m 1 "^Version:" "$BUILD_DIR/wp-content/themes/$slug/style.css" 2>/dev/null | \
sed 's/Version: //' | tr -d '[:space:]' || \
echo "inconnue")
THEME_INSTALLED=true
echo "[Build] Thème installé et activé : $slug (v$THEME_VERSION)"
return 0
else
echo "[Build] ATTENTION : L'installation du thème a échoué pour le slug : $slug"
THEME_INSTALLED=false
return 1
fi
}
# Tentative 1 : Installer le thème sélectionné par l'API ou la liste organisée
if ! install_theme "$THEME_SLUG"; then
# Tentative 2 : Si le thème sélectionné par l'API a échoué, essayer le repli organisé
if [ "$API_AVAILABLE" = "true" ]; then
echo "[Build] Tentative avec le thème de repli organisé pour la catégorie du site..."
# Claude détermine le slug de repli organisé à partir de la catégorie du site NL_PROMPT
# (voir la liste organisée de la Section 2) et réessaie
FALLBACK_SLUG="twentytwentyfour" # Claude remplace ceci par un slug spécifique à la catégorie si applicable
if ! install_theme "$FALLBACK_SLUG"; then
# Tentative 3 : Dernier recours — twentytwentyfour (maintenu par WordPress.org)
if [ "$FALLBACK_SLUG" != "twentytwentyfour" ]; then
echo "[Build] Tentative du dernier recours : twentytwentyfour..."
if ! install_theme "twentytwentyfour"; then
# Dernier repli — enregistrer un avertissement et continuer avec le thème par défaut de WordPress
echo "[Build] ATTENTION : Toutes les tentatives d'installation du thème ont échoué."
echo "[Build] ATTENTION : La construction se poursuit avec le thème par défaut de WordPress."
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="inconnue"
THEME_INSTALLED=false
fi
else
# twentytwentyfour a déjà échoué — continuer avec le thème par défaut
echo "[Build] ATTENTION : Toutes les tentatives d'installation du thème ont échoué."
echo "[Build] ATTENTION : La construction se poursuit avec le thème par défaut de WordPress."
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="inconnue"
THEME_INSTALLED=false
fi
fi
else
# Le thème organisé a échoué — essayer twentytwentyfour comme dernier recours
if [ "$THEME_SLUG" != "twentytwentyfour" ]; then
echo "[Build] Tentative du dernier recours : twentytwentyfour..."
if ! install_theme "twentytwentyfour"; then
echo "[Build] ATTENTION : Toutes les tentatives d'installation du thème ont échoué."
echo "[Build] ATTENTION : La construction se poursuit avec le thème par défaut de WordPress."
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="inconnue"
THEME_INSTALLED=false
fi
else
echo "[Build] ATTENTION : Toutes les tentatives d'installation du thème ont échoué."
echo "[Build] ATTENTION : La construction se poursuit avec le thème par défaut de WordPress."
THEME_SLUG="default"
THEME_NAME="WordPress Default"
THEME_VERSION="inconnue"
THEME_INSTALLED=false
fi
fi
fi
# Nettoyer le fichier de réponse temporaire de l'API
rm -f "$FSE_THEMES_FILE"
Section 4 : Mise à jour du titre du site
Mettez à jour le titre et le slogan du site WordPress pour qu'ils correspondent au site décrit dans NL_PROMPT. Le titre du site a déjà été défini lors de l'installation WP de build-scaffold (--title="$SITE_TITLE"), mais cette étape permet de définir le slogan avec une description contextuelle générée à partir du prompt NL.
echo "[Build] Définition du titre et du slogan du site..."
# Mettre à jour le titre du site (peut déjà correspondre à --title de build-scaffold, mais mise à jour pour confirmation)
$WP option update blogname "$SITE_TITLE" 2>&1
# Claude génère un slogan court (une ligne, sans guillemets) à partir du NL_PROMPT
# Exemples :
# NL_PROMPT : "un site portfolio pour un photographe freelance"
# → Slogan : "Capturer les moments qui comptent"
#
# NL_PROMPT : "un site de restaurant pour un bistrot italien à Sydney"
# → Slogan : "Saveurs italiennes authentiques au cœur de Sydney"
#
# Claude définit SITE_TAGLINE sur le slogan généré, puis :
SITE_TAGLINE="<slogan généré par Claude à partir du NL_PROMPT>"
$WP option update blogdescription "$SITE_TAGLINE" 2>&1
echo "[Build] Titre du site défini : $SITE_TITLE"
echo "[Build] Slogan du site défini : $SITE_TAGLINE"
Notes d'implémentation
Position dans le pipeline : Cette compétence s'exécute dans le pipeline de construction NL strictement APRÈS build-mcp Section 2 (adaptateur MCP activé, base de données réexportée) et AVANT build-content. Le thème doit être actif avant l'ensemencement du contenu car build-content utilise $WP menu location list pour découvrir les emplacements de navigation du thème actif — cela nécessite que le thème cible soit déjà installé et actif.
Conteneur Docker MySQL : Le conteneur Docker MySQL éphémère de build-scaffold Section 3 doit toujours être en cours d'exécution lorsque cette compétence s'exécute. L'installation du thème par WP-CLI écrit dans la table des options de WordPress (slug du thème actif). Le trap EXIT défini dans build-scaffold Section 3 reste actif pendant toute la session de construction et se déclenche uniquement lorsque la commande complète se termine — pas entre les invocations de compétences.
Variables de sortie : Les variables suivantes sont définies par cette compétence et consommées par les compétences en aval (build-content, build-setup) :
THEME_SLUG— slug du thème installé (par exempletwentytwentyfour,flavor)THEME_NAME— nom d'affichage (par exempleTwenty Twenty-Four,Flavor)THEME_VERSION— chaîne de version installée (par exemple1.3,inconnuesi indétectable)THEME_INSTALLED—truesi l'installation a réussi,falsesi tous les replis ont échoué
Maintenance de la liste de repli organisée : La liste organisée associe des catégories de sites à des thèmes FSE connus sur WP.org. Si un slug de thème organisé est supprimé de WP.org (provoquant l'échec de wp theme install avec "non trouvé"), mettez à jour cette liste avec un remplacement compatible FSE actuel. twentytwentyfour est le repli de dernier recours garanti — il est maintenu par l'équipe principale de WordPress.org et ne sera pas supprimé.
Aucune personnalisation après installation (décision verrouillée) : Conformément à la décision de l'utilisateur capturée dans CONTEXT.md, aucune substitution de theme.json, thème enfant ou modification des styles globaux n'est appliquée après l'installation. Le thème est installé et activé tel quel depuis WP.org. Son design intégré est livré en l'état.
Fiabilité de la validation FSE : La vérification de theme.json est une confirmation secondaire — Claude a déjà filtré les thèmes par le tag full-site-editing dans la requête API. Un message "ATTENTION : theme.json non trouvé" n'indique pas une erreur : le thème peut stocker theme.json à un emplacement non standard, ou le tag WP.org a peut-être été défini correctement mais la vérification du chemin du fichier a échoué. La construction continue quoi qu'il arrive.
Références :
- @references/wp-block-themes/SKILL.md — structure des thèmes FSE, schéma theme.json, modèles de blocs
- @references/wp-wpcli-and-ops/SKILL.md — référence des commandes de thème WP-CLI, indicateur --activate, sortie --field