Introduction: Le Défi des Développeurs WooCommerce
Vous développez pour WooCommerce depuis quelque temps? Alors vous connaissez ce sentiment: vous cherchez LE hook parfait, vous scrollez dans la documentation officielle, mais vous n’arrivez pas à trouver rapidement ce que vous cherchez.
WooCommerce c’est plus de 1000 hooks et fonctions dispersées dans le code source. C’est puissant, oui. Mais c’est aussi compliqué à naviguer.
Le problème
- Documentation officielle trop générique
- Pas d’exemples contextualisés
- Difficile de trouver LE hook pour mon use case
- Pas de catégorisation logique
- Perte de temps énorme pour chaque développement
La solution
Créer votre propre documentation structurée, catégorisée, avec exemples pratiques. Et l’automatiser au maximum!
C’est ce que nous allons explorer ensemble dans cet article. À la fin, vous saurez comment générer une documentation professionnelle de 1000+ pages en quelques secondes.
1. Avant de Commencer: Planification et Décisions
Avant de vous lancer dans la rédaction (ou plutôt dans l’automatisation), prenons un moment pour bien comprendre ce que vous voulez créer.
Quelle est votre audience?
Question fondamentale: Pour qui créez-vous cette documentation?
- Développeurs débutants? Besoin d’explications simples, exemples basiques
- Développeurs avancés? Focus sur les cas complexes, optimisations
- Votre équipe interne? Format adapté à vos pratiques
- Le public général? Professionnalisme maximum, design attrayant
À Condorito.fr, nous avons choisi: développeurs WordPress/WooCommerce de niveau intermédiaire à avancé.
Quels éléments inclure?
Chaque page devrait contenir:
- Le nom du hook/fonction
- Son type (action, filtre, ou fonction)
- Sa location dans le code
- Les paramètres
- Un exemple de code contextualisé et fonctionnel
- Une catégorie/tag pour l’organisation
Optionnel mais très utile:
- Description en français (si audience francophone)
- Cas d’usage réels
- Références vers d’autres hooks connexes
Choisir votre version de WooCommerce
Soyez explicite: « Cette documentation couvre WooCommerce 10.2.2 »
Pourquoi? Parce que les hooks changent entre les versions. Un hook retiré à la v11 ne doit pas être documenté si vous ciblez la v10.
// Dans votre configuration
WC_VERSION = "10.2.2"
GITHUB_REPO_URL = f"https://github.com/woocommerce/woocommerce/blob/{WC_VERSION}/plugins"
2. Comprendre les Hooks WooCommerce: Les Bases
Avant d’extraire, il faut comprendre ce qu’on extrait.
Les Trois Types de Hooks
1. Les Hooks d’Action (do_action)
// Dans le code WooCommerce (exemple simplifié)
do_action('woocommerce_new_order', $order_id);
// Votre code (injection)
add_action('woocommerce_new_order', 'ma_fonction', 10, 1);
function ma_fonction($order_id) {
// Faire quelque chose après création de commande
error_log("Nouvelle commande: " . $order_id);
}
Analogie: Un événement radio. WooCommerce crie « une commande a été créée! », et vous pouvez écouter cet événement et réagir.
2. Les Hooks de Filtre (apply_filters)
// Dans le code WooCommerce
$total = apply_filters('woocommerce_cart_total', $total);
// Votre code (modification)
add_filter('woocommerce_cart_total', 'modifier_total_panier', 10, 1);
function modifier_total_panier($total) {
// Appliquer une remise personnalisée
if (is_user_logged_in() && current_user_can('wholesale')) {
return $total * 0.8; // -20%
}
return $total;
}
Analogie: Un tuyau d’eau. WooCommerce envoie une valeur, vous la modifiez, vous la renvoyez transformée.
3. Les Fonctions Publiques
// Fonction disponible n'importe où
$product = wc_get_product(42);
// Utilisation basique
if ($product) {
echo $product->get_name(); // Affiche le nom du produit
}
Analogie: Une boîte à outils. Vous appelez une fonction, elle retourne un résultat.
La Différence: Hooks vs Fonctions
| Aspect | Hook | Fonction |
|---|---|---|
| Quand l’utiliser | Intervenir au bon moment | Récupérer/modifier des données |
| Exemple | woocommerce_new_order | wc_get_order() |
| Syntaxe | add_action() / add_filter() | Appel direct |
| Timing | À un moment spécifique | N’importe quand |
3. Architecture: Comment Tout Fonctionne Ensemble
Avant de coder, voyons le big picture. Voici comment se structure une documentation WooCommerce auto-générée:
├── Documentation Source
│ ├── Code WooCommerce (PHP)
│ ├── Fichier d'exemples (JSON)
│ └── Configuration (Python)
│
├── Traitement (Python Scripts)
│ ├── PHPParser (extraction)
│ ├── HTMLGenerator (génération)
│ └── Optimisations (traduction, SEO)
│
└── Documentation HTML (sortie)
├── index.html (page d'accueil)
├── hook-name.html (pages individuelles)
├── tag-category.html (pages par catégorie)
└── all.html (liste complète)
Flux général
- Parser le code source WooCommerce → Extraire hooks/fonctions
- Enrichir avec exemples (fichier JSON)
- Assigner des tags/catégories
- Générer pages HTML individuelles
- Créer index, pages de tags, moteur de recherche
- Publier en ligne
Élégant, non?
4. Étape 1: Extraire les Hooks avec PHPParser
C’est le cœur du système. On va parser le code PHP de WooCommerce et en extraire tous les hooks.
Comment Fonctionne le Parser
Le principe est simple: utiliser des expressions régulières (regex) pour trouver les patterns.
// Pattern pour trouver do_action (hooks d'action)
action_pattern = r'do_action\s*\(\s*[\'"]([^\'"]+)[\'"]\s*(?:,\s*(.+?))?\s*\)'
// Ce qu'il cherche:
// do_action('hook_name', $param1, $param2)
// do_action("hook_name", $var)
// do_action( 'hook_name' )
Ce que le regex fait:
do_action\s*\(: Cherche « do_action( » avec espaces optionnels[\'"]([^\'"]+)[\'"]: Capture le nom du hook entre guillemets(?:,\s*(.+?))?: Capture optionnellement les paramètres après la virgule\s*\): Cherche la parenthèse fermante
Résultat:
- Trouvé 1500 do_action
- Trouvé 800 apply_filters
- Trouvé 2300 fonctions publiques
- Total: ~4600 items
Extraction des Métadonnées
Pour chaque hook trouvé, on extrait aussi:
class PHPParser:
def parse_file(self, file_path):
# Pour chaque match regex trouvé:
self.items.append({
'type': 'action',
'name': 'woocommerce_new_order',
'file': 'includes/class-wc-order.php',
'line': 342,
'params': '$order_id',
'docblock': '/** ... */',
})
Code Complet: Le PHPParser
import re
import os
class PHPParser:
def __init__(self, source_dir):
self.source_dir = source_dir
self.items = []
def parse_directory(self):
"""Parcourt tous les fichiers PHP"""
for root, dirs, files in os.walk(self.source_dir):
dirs[:] = [d for d in dirs if d not in ['vendor', 'node_modules', '.git']]
for file in files:
if file.endswith('.php'):
file_path = os.path.join(root, file)
self.parse_file(file_path)
return self.items
def parse_file(self, file_path):
"""Extrait hooks et fonctions d'un fichier"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
except:
return
relative_path = os.path.relpath(file_path, self.source_dir)
# EXTRAIRE do_action (HOOKS D'ACTION)
action_pattern = r'do_action\s*\(\s*[\'"]([^\'"]+)[\'"]\s*(?:,\s*(.+?))?\s*\)'
for match in re.finditer(action_pattern, content):
hook_name = match.group(1)
params = match.group(2) if match.group(2) else ""
self.items.append({
'type': 'action',
'name': hook_name,
'file': relative_path,
'params': params.strip(),
'docblock': self.extract_docblock(content, match.start()),
'line': content[:match.start()].count('\n') + 1
})
# EXTRAIRE apply_filters (HOOKS DE FILTRE)
filter_pattern = r'apply_filters\s*\(\s*[\'"]([^\'"]+)[\'"]\s*(?:,\s*(.+?))?\s*\)'
for match in re.finditer(filter_pattern, content):
hook_name = match.group(1)
params = match.group(2) if match.group(2) else ""
self.items.append({
'type': 'filter',
'name': hook_name,
'file': relative_path,
'params': params.strip(),
'docblock': self.extract_docblock(content, match.start()),
'line': content[:match.start()].count('\n') + 1
})
# EXTRAIRE FONCTIONS PUBLIQUES
func_pattern = r'(public\s+|static\s+)*function\s+([a-zA-Z_]\w*)\s*\((.*?)\)'
for match in re.finditer(func_pattern, content, re.DOTALL):
func_name = match.group(2)
params = match.group(3)
if func_name.startswith('_'):
continue
self.items.append({
'type': 'function',
'name': func_name,
'file': relative_path,
'params': params.strip(),
'docblock': self.extract_docblock(content, match.start()),
'line': content[:match.start()].count('\n') + 1
})
def extract_docblock(self, content, position):
"""Extrait la documentation PHP au-dessus d'un élément"""
before = content[:position]
matches = list(re.finditer(r'/\*\*.*?\*/', before, re.DOTALL))
return matches[-1].group(0) if matches else ""
# Utilisation
if __name__ == "__main__":
parser = PHPParser("./woocommerce")
items = parser.parse_directory()
print(f"Found {len(items)} items")
for item in items[:5]:
print(f" - {item['type'].upper()}: {item['name']}")
Output:
Found 4621 items - ACTION: woocommerce_new_order - ACTION: woocommerce_order_status_changed - FILTER: woocommerce_cart_item_price - FILTER: woocommerce_product_get_price - FUNCTION: wc_get_order
Voilà. Vous avez maintenant une liste structurée de tous les hooks.
5. Étape 2: Enrichir avec des Exemples Pratiques
Une liste c’est bien. Mais une liste avec des exemples de code contextualisés, c’est infiniment mieux.
Créer le Fichier d’Exemples (JSON)
{
"woocommerce_new_order": {
"title": "Nouvelle Commande Créée",
"description": "Déclenché après la création d'une nouvelle commande. Parfait pour envoyer des notifications personnalisées.",
"tags": ["order-flow", "technical"],
"code": "add_action('woocommerce_new_order', 'notifier_nouvelle_commande', 10, 1);\n\nfunction notifier_nouvelle_commande($order_id) {\n $order = wc_get_order($order_id);\n $customer_email = $order->get_billing_email();\n \n wp_mail(\n 'admin@exemple.com',\n 'Nouvelle commande #' . $order_id,\n 'Total: ' . $order->get_total() . 'EUR'\n );\n}"
},
"woocommerce_product_get_price": {
"title": "Modifier le Prix d'un Produit",
"description": "Permet de modifier dynamiquement le prix. Idéal pour les remises conditionnelles.",
"tags": ["pricing", "products"],
"code": "add_filter('woocommerce_product_get_price', 'prix_grossiste', 10, 2);\n\nfunction prix_grossiste($price, $product) {\n if (is_user_logged_in() && current_user_can('wholesale')) {\n return $price * 0.8;\n }\n return $price;\n}"
},
"woocommerce_add_to_cart": {
"title": "Article Ajouté au Panier",
"description": "Se déclenche après l'ajout d'un article au panier.",
"tags": ["cart", "technical"],
"code": "add_action('woocommerce_add_to_cart', 'tracking_ajout_panier', 10, 6);\n\nfunction tracking_ajout_panier($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {\n $product = wc_get_product($product_id);\n error_log(\"Produit ajouté: {$product->get_name()} x{$quantity}\");\n}"
}
}
Charger les Exemples dans le Generator
import json
class HTMLGenerator:
def __init__(self, output_dir, examples_file="./woo-examples.json"):
self.output_dir = output_dir
self.examples = self.load_examples()
def load_examples(self):
"""Charge les exemples depuis JSON"""
if os.path.exists(self.examples_file):
try:
with open(self.examples_file, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"Erreur chargement exemples: {e}")
return {}
return {}
def get_example_metadata(self, hook_name):
"""Récupère titre, description, tags d'un exemple"""
if hook_name in self.examples:
example = self.examples[hook_name]
return {
'title': example.get('title', ''),
'description': example.get('description', ''),
'tags': example.get('tags', []),
}
return None
6. Étape 3: Les Tags – Organiser avec Logique
Avec 4600 items, il faut une organisation. Les tags (catégories) sont LA clé.
Les 7 Catégories WooCommerce
Nous avons choisi 7 catégories qui couvrent 95% des use cases:
TAG_CATEGORIES = {
'order-flow': {
'icon': 'fa-solid fa-box-open',
'label': 'Tunnel d\'Achat',
'description': 'Tout le processus de commande'
},
'products': {
'icon': 'fa-solid fa-boxes-stacked',
'label': 'Gestion Produits',
'description': 'Catalogue et variations'
},
'cart': {
'icon': 'fa-solid fa-cart-shopping',
'label': 'Panier',
'description': 'Gestion du panier'
},
'pricing': {
'icon': 'fa-solid fa-tag',
'label': 'Tarification',
'description': 'Prix et remises'
},
'ui': {
'icon': 'fa-solid fa-display',
'label': 'Interface',
'description': 'Messages et formulaires'
},
'account': {
'icon': 'fa-solid fa-user',
'label': 'Espace Client',
'description': 'Comptes et profils'
},
'technical': {
'icon': 'fa-solid fa-screwdriver-wrench',
'label': 'Utilitaires',
'description': 'Briques techniques'
}
}
Assigner les Tags dans le JSON
Chaque exemple obtient des tags:
{
"woocommerce_new_order": {
"tags": ["order-flow", "technical"],
...
},
"woocommerce_checkout_fields": {
"tags": ["ui", "order-flow"],
...
}
}
Logique:
- Chaque hook peut avoir 1-3 tags max (pour éviter la surcharge)
- Les tags principaux sont listés en priorité
- Les items sans tags font partie d’une section « Autres »
7. Étape 4: Générer les Pages HTML
C’est ici que la magie opère. En quelques secondes, générer 4600 pages HTML.
Code Python pour Générer les Pages
class HTMLGenerator:
def generate_page(self, item, cross_refs=None):
"""Génère une page HTML pour chaque hook/fonction"""
safe_name = self.sanitize_filename(item['name'])
filename = f"{safe_name}.html"
filepath = os.path.join(self.output_dir, filename)
example_meta = self.get_example_metadata(item['name'])
should_translate = example_meta and example_meta.get('tags')
code_example = self.generate_code_example(item)
html_content = f"""<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>{item['name']} - Documentation WooCommerce</title>
<link rel="stylesheet" href="../style2.css">
</head>
<body>
{self.get_header(item['name'], breadcrumb)}
<div>
<h1>{item['name']}</h1>
<div>
<span>{item['type'].upper()}</span>
<span>{item['file']} (ligne {item.get('line', '?')})</span>
</div>
<div>
{self.format_docblock(item['docblock'], should_translate)}
</div>
<div>
<h2>Paramètres</h2>
{self.extract_params_from_docblock(item['docblock'], should_translate)}
</div>
<div>
<h2>Exemple</h2>
<pre>{code_example}</pre>
</div>
</div>
{self.get_footer()}
</body>
</html>"""
with open(filepath, 'w', encoding='utf-8') as f:
f.write(html_content)
return filepath
# Utilisation
if __name__ == "__main__":
generator = HTMLGenerator("./output")
for i, item in enumerate(items, 1):
generator.generate_page(item)
if i % 100 == 0:
print(f"{i}/4621 pages générées...")
print("Documentation générée!")
Performance:
- ~4600 pages en ~30 secondes
- ~50MB d’HTML statique
- Prêt pour publication
8. Optimisations Majeures
Traduction Intelligente: Économiser 70% de Crédits API
WooCommerce étant anglophone, vous voudrez peut-être traduire les descriptions. Mais attention aux coûts.
Problème: Traduire 4600 items = coûts énormes
Solution: Traduire SEULEMENT les items avec exemples (les taggés)
def format_translated_content(self, original_text, should_translate=True):
"""Formate le contenu avec traduction optionnelle"""
if not original_text:
return ""
if should_translate:
translated = translate_to_french(original_text)
else:
translated = original_text
if not should_translate:
return f"<div><pre>{original_text}</pre></div>"
return f"""
<div><pre>{original_text}</pre></div>
<details>
<summary>traduction française</summary>
<pre>{translated}</pre>
</details>
"""
Résultat:
- Items avec exemples (500) = traduction complète
- Items sans exemples (4100) = aucune traduction
- Économie: 89% de réduction d’API calls
Moteur de Recherche Instantané
Générer un index JSON pour une recherche au clavier:
def generate_search_index(self, items):
"""Génère un index de recherche en JSON"""
search_data = []
for item in items:
search_data.append({
'name': item['name'],
'type': item['type'],
'url': f"{self.sanitize_filename(item['name'])}.html",
'tags': self.get_example_metadata(item['name']).get('tags', [])
})
with open(os.path.join(self.output_dir, 'search-index.json'), 'w') as f:
json.dump(search_data, f)
SEO: Sitemap et Meta Descriptions
def generate_sitemap(self, items, base_url):
"""Génère sitemap.xml pour le référencement"""
xml = '<?xml version="1.0" encoding="UTF-8"?>\n'
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
for item in items:
safe_name = self.sanitize_filename(item['name'])
xml += f"""
<url>
<loc>{base_url}/docs/{safe_name}.html</loc>
<lastmod>{date.today()}</lastmod>
<priority>0.8</priority>
</url>
"""
xml += '</urlset>'
with open(os.path.join(self.output_dir, 'sitemap.xml'), 'w') as f:
f.write(xml)
9. L’Interface Utilisateur: Un Design Professionnel
Votre documentation doit être belle. C’est du code, pas un PDF.
Palette Couleurs WooCommerce
:root {
--primary: #e0040b;
--secondary: #fc5130;
--dark: #2c3e50;
--light: #ecf0f1;
}
.hero-intro {
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
color: white;
padding: 5rem 2rem;
text-align: center;
}
.tag-card {
background: white;
border: 1px solid #e0e0e0;
border-top: 4px solid var(--primary);
border-radius: 15px;
padding: 2rem;
transition: transform 0.3s;
}
.tag-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 40px rgba(224, 4, 11, 0.2);
}
Responsive Design Mobile
@media (max-width: 768px) {
.tags-grid {
grid-template-columns: 1fr;
}
.hero-intro h1 {
font-size: 2rem;
}
.tag-card {
padding: 1.5rem;
}
}
10. Mise en Production: Publier Votre Documentation
Où Héberger?
Options recommandées:
1. Netlify/Vercel (gratuit, facile)
netlify deploy --prod --dir ./output
2. GitHub Pages (gratuit)
git add output/ git commit -m "Update docs" git push
3. Votre serveur (plus de contrôle)
scp -r ./output/* user@server:/var/www/docs/
Automatiser la Génération
Créer un script qui se déclenche tous les mois:
#!/bin/bash # regenerate-docs.sh cd /home/docs python3 doc-gen21.py git add output/ git commit -m "Auto-generated docs - $(date)" git push origin main
Cron job:
0 0 1 * * /home/docs/regenerate-docs.sh >> /home/docs/cron.log 2>&1
11. Résultats et Métriques
Avant vs Après
| Aspect | Avant | Après |
|---|---|---|
| Trouver LE hook | 15-30 min | < 1 min |
| Nombre de pages | 0 | 4600+ |
| Exemples | 0 | 500+ |
| Temps de dev | +30 min/tâche | -10 min/tâche |
Métriques Réelles (Condorito.fr)
Pages générées: 4,621 Temps de génération: 28 secondes Taille totale: 145 MB Hooks avec exemples: 523 (11%) Traductions sauvegardées: 4,098 (89% d'économie API!) Trafic mensuel: ~8,500 visiteurs Pages les plus consultées: 1. woocommerce_new_order 2. woocommerce_product_get_price 3. wc_get_order 4. woocommerce_add_to_cart 5. woocommerce_checkout_fields Temps moyen sur site: 3:45 min Taux de rebond: 22%
Conclusion: C’est à Votre Tour
Créer une documentation complète de WooCommerce paraît compliqué au premier abord. Mais avec l’approche étape par étape que nous venons de voir, c’est étonnamment accessible.
Récapitulatif des étapes
- Parser le code source avec regex
- Enrichir avec exemples en JSON
- Catégoriser avec des tags logiques
- Générer les pages HTML automatiquement
- Optimiser (traduction, SEO, recherche)
- Designer une UI professionnelle
- Publier et maintenir
Bénéfices Concrets
- Économie: 89% moins d’appels API
- Rapidité: Trouver l’info en < 1 minute
- Qualité: Documentation professionnelle
- SEO: 4600+ pages indexées
- Productivité: -30 min par développement
Prochaines Étapes
Vous voulez la mettre en place? Récupérez le script, adaptez aux vos besoins, ajoutez vos propres exemples, et publiez.
Des questions? Commentez ci-dessous ou contactez-nous directement. Rejoignez notre newsletter pour les mises à jour.
