2 min de lecture · 275 mots

WordPress : API et fonctions essentielles

WordPress : API et fonctions essentielles

Structure et concepts de base

Hiérarchie des templates

Page d'accueil:     front-page.php → home.php → index.php
Article seul:       single-{post-type}.php → single.php → singular.php → index.php
Page:               page-{slug}.php → page-{id}.php → page.php → singular.php → index.php
Archive:            archive-{post-type}.php → archive.php → index.php
Catégorie:          category-{slug}.php → category-{id}.php → category.php → archive.php → index.php
Tag:                tag-{slug}.php → tag-{id}.php → tag.php → archive.php → index.php
Auteur:             author-{nicename}.php → author-{id}.php → author.php → archive.php → index.php
Date:               date.php → archive.php → index.php
Recherche:          search.php → index.php
404:                404.php → index.php
Attachement:        attachment.php → single-attachment-{type}.php → single.php → index.php

Structure d’un thème

mon-theme/
├── style.css              (requis)
├── index.php              (requis)
├── functions.php          (fonctions du thème)
├── header.php
├── footer.php
├── sidebar.php
├── single.php
├── page.php
├── archive.php
├── category.php
├── tag.php
├── search.php
├── 404.php
├── front-page.php
├── home.php
├── comments.php
├── screenshot.png
├── template-parts/
│   ├── content.php
│   ├── content-single.php
│   └── content-page.php
├── inc/
│   ├── customizer.php
│   └── template-functions.php
└── assets/
    ├── css/
    ├── js/
    └── images/

En-tête style.css (thème)

/
Theme Name: Mon Thème
Theme URI: https://example.com/mon-theme
Author: Votre Nom
Author URI: https://example.com
Description: Description de votre thème
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: mon-theme
Tags: blog, two-columns, custom-header, custom-menu
/

Structure d’un plugin

mon-plugin/
├── mon-plugin.php         (fichier principal)
├── uninstall.php          (désinstallation)
├── readme.txt
├── includes/
│   ├── class-activator.php
│   ├── class-deactivator.php
│   └── class-main.php
├── admin/
│   ├── class-admin.php
│   ├── css/
│   └── js/
└── public/
    ├── class-public.php
    ├── css/
    └── js/

En-tête plugin principal


  Plugin Name: Mon Plugin
  Plugin URI: https://example.com/mon-plugin
  Description: Description de votre plugin
  Version: 1.0.0
  Requires at least: 6.0
  Requires PHP: 8.0
  Author: Votre Nom
  Author URI: https://example.com
  License: GPL v2 or later
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
  Text Domain: mon-plugin
  Domain Path: /languages
 /

if (!defined('ABSPATH')) {
    exit; // Protection accès direct
}

define('MONPLUGINVERSION', '1.0.0');
define('MONPLUGINPATH', plugindirpath(FILE));
define('MONPLUGINURL', plugindirurl(FILE));

Hooks : Actions et Filtres

Actions principales

action('init', 'mafonctioninit');
addaction('admininit', 'mafonctionadmininit');
addaction('wploaded', 'mafonctionloaded');

// Enqueue scripts et styles
addaction('wpenqueuescripts', 'messcriptsstyles');
addaction('adminenqueuescripts', 'messcriptsadmin');
addaction('loginenqueuescripts', 'messcriptslogin');

function messcriptsstyles() {
    wpenqueuestyle(
        'mon-style',
        getstylesheetdirectoryuri() . '/assets/css/style.css',
        [],
        '1.0.0'
    );

    wpenqueuescript(
        'mon-script',
        gettemplatedirectoryuri() . '/assets/js/script.js',
        ['jquery'],
        '1.0.0',
        true
    );

    // Localiser script (passer variables PHP à JS)
    wplocalizescript('mon-script', 'monObjet', [
        'ajaxUrl' => adminurl('admin-ajax.php'),
        'nonce' => wpcreatenonce('mon-nonce'),
        'texte' => ('Mon texte', 'mon-theme'),
    ]);
}

// Templates
addaction('wphead', 'mafonctionhead');
addaction('wpfooter', 'mafonctionfooter');
addaction('getheader', 'avantheader');
addaction('getfooter', 'avantfooter');

// Contenu
addaction('thepost', 'mafonctionpost');
addaction('loopstart', 'debutloop');
addaction('loopend', 'finloop');

// Enregistrement/Modification
addaction('savepost', 'mafonctionsave', 10, 2);
addaction('wpinsertpost', 'mafonctioninsert', 10, 3);
addaction('beforedeletepost', 'avantsuppression');
addaction('deletedpost', 'apressuppression');

// Utilisateurs
addaction('userregister', 'nouvelutilisateur');
addaction('profileupdate', 'majprofil', 10, 2);
addaction('deleteuser', 'suppressionutilisateur');

// Widgets
addaction('widgetsinit', 'meswidgets');

function meswidgets() {
    registersidebar([
        'name' => ('Sidebar Principale', 'mon-theme'),
        'id' => 'sidebar-1',
        'beforewidget' => '
', 'afterwidget' => '
', 'beforetitle' => '

', 'after

title' => '', ]); } // AJAX addaction('wpajaxmonaction', 'mafonctionajax'); addaction('wpajaxnoprivmonaction', 'mafonctionajax'); // Pour non-connectés function mafonctionajax() { checkajaxreferer('mon-nonce', 'nonce'); $data = $POST['data'] ?? ''; // Traitement... wpsendjsonsuccess(['message' => 'Succès']); // ou wpsendjsonerror(['message' => 'Erreur']); } // Activation/Désactivation plugin registeractivationhook(FILE, 'monpluginactivation'); registerdeactivationhook(FILE, 'monplugindesactivation'); // Cron addaction('moncronhook', 'matachecron'); if (!wpnextscheduled('moncronhook')) { wpscheduleevent(time(), 'daily', 'moncronhook'); } // Priorité et arguments addaction('init', 'mafonction', 10, 1); // 10 = priorité (défaut), 1 = nb args

Filtres principaux

filter('thecontent', 'modifiercontenu');
addfilter('theexcerpt', 'modifierextrait');
addfilter('thetitle', 'modifiertitre', 10, 2);

function modifiercontenu($content) {
    // Modifier contenu
    return $content . '

Ajout en fin

'; } // Longueur extrait add
filter('excerptlength', 'nouvellelongueurextrait'); function nouvellelongueurextrait($length) { return 30; // mots } addfilter('excerptmore', 'nouveaumore'); function nouveaumore($more) { return '... Lire plus'; } // Requêtes addfilter('pregetposts', 'modifierrequete'); function modifierrequete($query) { if (!isadmin() && $query->ismainquery() && $query->ishome()) { $query->set('postsperpage', 12); $query->set('orderby', 'date'); } return $query; } // Upload addfilter('uploadmimes', 'ajoutertypesmime'); function ajoutertypesmime($mimes) { $mimes['svg'] = 'image/svg+xml'; return $mimes; } addfilter('wphandleuploadprefilter', 'filtrerupload'); // Admin addfilter('adminfootertext', 'customadminfooter'); addfilter('loginredirect', 'maredirectionlogin', 10, 3); // Email addfilter('wpmailfrom', 'custommailfrom'); addfilter('wpmailfromname', 'custommailfromname'); function custommailfrom($email) { return 'noreply@monsite.com'; } // Menu addfilter('wpnavmenuitems', 'ajouteritemmenu', 10, 2); // Body class addfilter('bodyclass', 'custombodyclass'); function custombodyclass($classes) { if (ispage('contact')) { $classes[] = 'page-contact-custom'; } return $classes; } // Sanitization addfilter('sanitizetitle', 'customsanitizetitle'); // Retirer un filtre removefilter('thecontent', 'wpautop'); // Retire auto-paragraphes

Créer ses propres hooks

fonction() {
    // Avant traitement
    doaction('monhookavant');

    // Traitement
    $resultat = "données";

    // Après traitement
    doaction('monhookapres', $resultat);

    return $resultat;
}

// Utiliser l'action
addaction('monhookavant', 'macallbackavant');
addaction('monhookapres', 'macallbackapres');

// Créer un filtre
function calculerprix($prix) {
    $prix = applyfilters('monfiltreprix', $prix);
    return $prix;
}

// Utiliser le filtre
addfilter('monfiltreprix', function($prix) {
    return $prix  1.2; // +20%
});

Template Tags (balises de template)

header();           // Inclut header.php
getheader('custom');   // Inclut header-custom.php

// footer.php
getfooter();
getfooter('custom');

// sidebar.php
getsidebar();
getsidebar('custom');

// Dans header.php
?>

attributes(); ?>>

    
    
    head(); ?>

class(); ?>>
bodyopen(); ?>

navmenu([ 'themelocation' => 'primary', 'menuclass' => 'nav-menu', 'container' => 'nav', ]); ?>

©

footer(); ?>

Loop (boucle WordPress)

posts()) :
    while (have
posts()) : thepost(); ?>
class(); ?>>

title(); ?>

post
thumbnail()) : ?>
postthumbnail('large'); ?>
excerpt(); // ou thecontent('Lire la suite'); ?>
postspagination([ 'midsize' => 2, 'prevtext' => ('« Précédent', 'mon-theme'), 'nexttext' => ('Suivant »', 'mon-theme'), ]); else : ?>

e('Aucun article trouvé.', 'mon-theme'); ?>

resetpostdata();

Template Parts

templatepart('template-parts/content', 'single');
// Cherche: content-single.php, puis content.php

gettemplatepart('template-parts/content', getposttype());
// Pour post-type "product": content-product.php

// Passer variables (WP 5.5+)
gettemplatepart('template-parts/card', null, [
    'title' => 'Mon titre',
    'data' => $data,
]);

// Dans le template part (content.php)
// Accéder aux variables avec $args
$title = $args['title'] ?? '';

Informations du site


getbloginfo('name');
homeurl('/');             // URL accueil
adminurl('admin.php');    // URL admin
siteurl();                // URL du site

Articles et pages

ID();                   // ID du post
thetitle();                // Titre
thepermalink();            // URL
thecontent();              // Contenu complet
theexcerpt();              // Extrait
theauthor();               // Nom auteur
theauthormeta('displayname'); // Meta auteur
thetime('F j, Y');        // Date personnalisée
thedate();                 // Date
themodifieddate();        // Date modification
thecategory(', ');        // Catégories
thetags('Tags: ', ', ');  // Tags
commentsnumber('0', '1', '%'); // Nombre commentaires

// Versions get (retournent, n'affichent pas)
gettheID();
getthetitle();
getthepermalink();
getthecontent();
gettheexcerpt();
gettheauthor();
getthedate('Y-m-d');
getthecategory();
getthetags();

// Images
thepostthumbnail('thumbnail');     // 150x150
thepostthumbnail('medium');        // 300x300
thepostthumbnail('large');         // 1024x1024
thepostthumbnail('full');          // Taille originale
thepostthumbnail([200, 300]);      // Taille personnalisée

getthepostthumbnailurl($postid, 'large');

if (haspostthumbnail()) {
    thepostthumbnail();
}

// Custom fields
getpostmeta($postid, 'cle', true);   // true = valeur unique
updatepostmeta($postid, 'cle', 'valeur');
deletepostmeta($postid, 'cle');
addpostmeta($postid, 'cle', 'valeur');

Taxonomies

category(', ');                     // Affiche
getthecategory();                     // Retourne array

// Tags
thetags('Tags: ', ', ', '
'); get
thetags(); // Termes personnalisés theterms($postid, 'ma-taxonomie', 'Prefix: ', ', '); gettheterms($postid, 'ma-taxonomie'); // Récupérer termes $terms = getterms([ 'taxonomy' => 'category', 'hideempty' => false, ]); foreach ($terms as $term) { echo $term->name; echo $term->slug; echo $term->termid; echo $term->count; } // URL terme gettermlink($term); getcategorylink($catid); gettaglink($tagid);

WPQuery : Requêtes personnalisées

Exemples de requêtes

type' => 'post',
    'postsperpage' => 10,
];
$query = new WPQuery($args);

if ($query->haveposts()) :
    while ($query->haveposts()) : $query->thepost();
        thetitle();
    endwhile;
    wpresetpostdata(); // Important !
endif;

// Requête avancée
$args = [
    'posttype' => 'product',
    'postsperpage' => 12,
    'orderby' => 'date',
    'order' => 'DESC',
    'poststatus' => 'publish',
    'author' => 1,
    'categoryname' => 'actualites',
    'tag' => 'featured',
    'metaquery' => [
        'relation' => 'AND',
        [
            'key' => 'prix',
            'value' => 100,
            'compare' => '<',
            'type' => 'NUMERIC',
        ],
        [
            'key' => 'disponible',
            'value' => '1',
            'compare' => '=',
        ],
    ],
    'taxquery' => [
        'relation' => 'AND',
        [
            'taxonomy' => 'productcat',
            'field' => 'slug',
            'terms' => 'electronics',
        ],
        [
            'taxonomy' => 'producttag',
            'field' => 'slug',
            'terms' => ['featured', 'new'],
            'operator' => 'IN',
        ],
    ],
    'datequery' => [
        [
            'after' => '2024-01-01',
            'before' => '2024-12-31',
            'inclusive' => true,
        ],
    ],
];

$query = new WPQuery($args);

// Paramètres utiles
$args = [
    // Post Type
    'posttype' => 'post',          // post, page, custom-post-type, any
    'posttype' => ['post', 'page'],

    // Nombre
    'postsperpage' => 10,         // -1 pour tous
    'nopaging' => true,             // Ignore pagination

    // Ordre
    'orderby' => 'date',            // date, title, name, modified, rand, metavalue, metavaluenum
    'order' => 'DESC',              // ASC ou DESC

    // Pagination
    'paged' => getqueryvar('paged') ?: 1,
    'offset' => 5,                  // Sauter X posts

    // Statut
    'poststatus' => 'publish',     // publish, draft, pending, private, trash, any

    // Auteur
    'author' => 1,                  // ID
    'authorname' => 'john',        // Slug

    // Inclusion/Exclusion
    'postin' => [1, 2, 3],       // IDs à inclure
    'postnotin' => [4, 5, 6],   // IDs à exclure

    // Taxonomie simple
    'categoryname' => 'news',      // Slug catégorie
    'cat' => 5,                     // ID catégorie
    'tag' => 'featured',            // Slug tag
    'tagid' => 10,                 // ID tag

    // Recherche
    's' => 'mot clé',

    // Post parent
    'postparent' => 10,            // ID du parent
    'postparentin' => [1, 2],
    'postparentnotin' => [3, 4],

    // Cache
    'cacheresults' => true,
    'updatepostmetacache' => true,
    'updateposttermcache' => true,
];

// Informations sur la requête
$query->foundposts;        // Total posts trouvés
$query->maxnumpages;      // Nombre de pages
$query->postcount;         // Posts dans page actuelle

Meta Query avancée

query' => [
        'relation' => 'AND', // AND ou OR
        [
            'key' => 'couleur',
            'value' => 'bleu',
            'compare' => '=',    // =, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN, EXISTS, NOT EXISTS
        ],
        [
            'key' => 'prix',
            'value' => [10, 100],
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC', // NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED
        ],
        [
            'relation' => 'OR',
            [
                'key' => 'promo',
                'value' => '1',
                'compare' => '=',
            ],
            [
                'key' => 'nouveau',
                'value' => '1',
                'compare' => '=',
            ],
        ],
    ],
];

// Ordonner par meta
$args = [
    'metakey' => 'prix',
    'orderby' => 'metavaluenum',
    'order' => 'ASC',
];

// Meta query avec clause nommée (pour orderby)
$args = [
    'metaquery' => [
        'prixclause' => [
            'key' => 'prix',
            'type' => 'NUMERIC',
        ],
        'noteclause' => [
            'key' => 'note',
            'type' => 'NUMERIC',
        ],
    ],
    'orderby' => [
        'prixclause' => 'ASC',
        'noteclause' => 'DESC',
    ],
];

Tax Query avancée

query' => [
        'relation' => 'AND',
        [
            'taxonomy' => 'category',
            'field' => 'slug',      // slug, termid, name
            'terms' => 'news',
            'operator' => 'IN',     // IN, NOT IN, AND, EXISTS, NOT EXISTS
        ],
        [
            'taxonomy' => 'posttag',
            'field' => 'slug',
            'terms' => ['featured', 'popular'],
            'operator' => 'IN',
        ],
        [
            'relation' => 'OR',
            [
                'taxonomy' => 'productcat',
                'field' => 'slug',
                'terms' => 'electronics',
            ],
            [
                'taxonomy' => 'productcat',
                'field' => 'slug',
                'terms' => 'clothing',
            ],
        ],
    ],
];

Fonctions alternatives

posts() - Retourne array de posts
$posts = getposts([
    'numberposts' => 5,
    'posttype' => 'post',
]);

foreach ($posts as $post) {
    setuppostdata($post); // Important pour template tags
    thetitle();
}
wpresetpostdata();

// getpages()
$pages = getpages([
    'sortcolumn' => 'menuorder',
    'parent' => 0,
]);

// Query principale
global $wpquery;
$wpquery->ishome();
$wpquery->issingle();
$wpquery->ispage();

Custom Post Types et Taxonomies

Register Post Type

customposttype() {
    $labels = [
        'name' => x('Produits', 'Post type general name', 'mon-theme'),
        'singularname' => x('Produit', 'Post type singular name', 'mon-theme'),
        'menuname' => x('Produits', 'Admin Menu text', 'mon-theme'),
        'addnew' => ('Ajouter nouveau', 'mon-theme'),
        'addnewitem' => ('Ajouter un nouveau produit', 'mon-theme'),
        'edititem' => ('Modifier le produit', 'mon-theme'),
        'newitem' => ('Nouveau produit', 'mon-theme'),
        'viewitem' => ('Voir le produit', 'mon-theme'),
        'searchitems' => ('Rechercher des produits', 'mon-theme'),
        'notfound' => ('Aucun produit trouvé', 'mon-theme'),
        'notfoundintrash' => ('Aucun produit dans la corbeille', 'mon-theme'),
        'allitems' => ('Tous les produits', 'mon-theme'),
    ];

    $args = [
        'labels' => $labels,
        'description' => ('Gestion des produits', 'mon-theme'),
        'public' => true,
        'publiclyqueryable' => true,
        'showui' => true,
        'showinmenu' => true,
        'queryvar' => true,
        'rewrite' => ['slug' => 'produits'],
        'capabilitytype' => 'post',
        'hasarchive' => true,
        'hierarchical' => false,        // false = comme post, true = comme page
        'menuposition' => 5,
        'menuicon' => 'dashicons-products',
        'supports' => ['title', 'editor', 'thumbnail', 'excerpt', 'comments', 'custom-fields'],
        'showinrest' => true,         // Active Gutenberg
        'taxonomies' => ['category', 'posttag'],
    ];

    registerposttype('product', $args);
}
addaction('init', 'moncustomposttype');

// Flush rewrite rules après activation
registeractivationhook(FILE, function() {
    moncustomposttype();
    flushrewriterules();
});

registerdeactivationhook(FILE, function() {
    flushrewriterules();
});

Register Taxonomy

customtaxonomy() {
    $labels = [
        'name' => x('Catégories Produits', 'taxonomy general name', 'mon-theme'),
        'singularname' => x('Catégorie Produit', 'taxonomy singular name', 'mon-theme'),
        'searchitems' => ('Rechercher catégories', 'mon-theme'),
        'allitems' => ('Toutes les catégories', 'mon-theme'),
        'parentitem' => ('Catégorie parente', 'mon-theme'),
        'parentitemcolon' => ('Catégorie parente:', 'mon-theme'),
        'edititem' => ('Modifier la catégorie', 'mon-theme'),
        'updateitem' => ('Mettre à jour', 'mon-theme'),
        'addnewitem' => ('Ajouter nouvelle catégorie', 'mon-theme'),
        'newitemname' => ('Nom nouvelle catégorie', 'mon-theme'),
        'menuname' => ('Catégories', 'mon-theme'),
    ];

    $args = [
        'labels' => $labels,
        'description' => ('Catégories de produits', 'mon-theme'),
        'hierarchical' => true,         // true = comme catégorie, false = comme tag
        'public' => true,
        'publiclyqueryable' => true,
        'showui' => true,
        'showinmenu' => true,
        'showinnavmenus' => true,
        'showadmincolumn' => true,
        'queryvar' => true,
        'rewrite' => ['slug' => 'categorie-produit'],
        'showinrest' => true,
    ];

    registertaxonomy('productcat', ['product'], $args);

    // Taxonomie non-hiérarchique (comme tags)
    registertaxonomy('producttag', ['product'], [
        'labels' => [
            'name' => 'Tags Produits',
            'singularname' => 'Tag Produit',
        ],
        'hierarchical' => false,
        'showadmincolumn' => true,
        'rewrite' => ['slug' => 'tag-produit'],
    ]);
}
addaction('init', 'macustomtaxonomy');
menus() {
    registernavmenus([
        'primary' => ('Menu Principal', 'mon-theme'),
        'footer' => ('Menu Footer', 'mon-theme'),
        'mobile' => ('Menu Mobile', 'mon-theme'),
    ]);
}
addaction('aftersetuptheme', 'mesmenus');

// Afficher menu
wpnavmenu([
    'themelocation' => 'primary',
    'menuclass' => 'nav-menu',
    'container' => 'nav',
    'containerclass' => 'primary-navigation',
    'fallbackcb' => 'wppagemenu',
    'depth' => 2,
]);

// Options avancées
wpnavmenu([
    'themelocation' => 'primary',
    'menu' => 'Main Menu',              // Nom du menu
    'menuid' => 'primary-menu',
    'menuclass' => 'nav-menu',
    'container' => 'nav',
    'containerid' => 'site-navigation',
    'containerclass' => 'primary-navigation',
    'before' => '',
    'after' => '',
    'linkbefore' => '',
    'linkafter' => '',
    'itemswrap' => '
    %3$s
', 'depth' => 0, // 0 = tous les niveaux 'walker' => new Mon
CustomWalker(), ]); // Walker personnalisé class MonCustomWalker extends WalkerNavMenu { function startel(&$output, $item, $depth = 0, $args = [], $id = 0) { $classes = empty($item->classes) ? [] : (array) $item->classes; $classnames = join(' ', applyfilters('navmenucssclass', arrayfilter($classes), $item)); $output .= '
  • '; $attributes = ''; $attributes .= !empty($item->url) ? ' href="' . escattr($item->url) . '"' : ''; $itemoutput = $args->before ?? ''; $itemoutput .= ''; $itemoutput .= ($args->linkbefore ?? '') . applyfilters('thetitle', $item->title, $item->ID) . ($args->linkafter ?? ''); $itemoutput .= ''; $itemoutput .= $args->after ?? ''; $output .= applyfilters('walkernavmenustartel', $itemoutput, $item, $depth, $args); } }
  • Base de données WordPress

    Tables principales

    wpposts            - Articles, pages, custom post types
    wppostmeta         - Meta données posts
    wpusers            - Utilisateurs
    wpusermeta         - Meta données utilisateurs
    wpcomments         - Commentaires
    wpcommentmeta      - Meta données commentaires
    wpterms            - Termes (catégories, tags, taxonomies)
    wptermtaxonomy    - Relations taxonomie
    wptermrelationships - Relations posts/termes
    wpoptions          - Options du site
    wplinks            - Liens (déprécié)
    

    wpdb – Requêtes SQL

    getresults("SELECT  FROM {$wpdb->posts} WHERE posttype = 'post'");
    
    foreach ($results as $post) {
        echo $post->posttitle;
    }
    
    // Récupérer une ligne
    $post = $wpdb->getrow("SELECT  FROM {$wpdb->posts} WHERE ID = 1");
    
    // Récupérer une colonne
    $titles = $wpdb->getcol("SELECT posttitle FROM {$wpdb->posts}");
    
    // Récupérer une valeur
    $count = $wpdb->getvar("SELECT COUNT() FROM {$wpdb->posts}");
    
    // Préparation sécurisée (IMPORTANT)
    $postid = 1;
    $posttype = 'product';
    $sql = $wpdb->prepare(
        "SELECT  FROM {$wpdb->posts} WHERE ID = %d AND posttype = %s",
        $postid,
        $posttype
    );
    $post = $wpdb->getrow($sql);
    
    // Placeholders: %d (int), %f (float), %s (string)
    
    // INSERT
    $wpdb->insert(
        $wpdb->posts,
        [
            'posttitle' => 'Mon titre',
            'postcontent' => 'Mon contenu',
            'poststatus' => 'publish',
            'posttype' => 'post',
        ],
        ['%s', '%s', '%s', '%s']
    );
    $insertid = $wpdb->insertid;
    
    // UPDATE
    $wpdb->update(
        $wpdb->posts,
        ['posttitle' => 'Nouveau titre'],      // Data
        ['ID' => 1],                             // Where
        ['%s'],                                  // Format data
        ['%d']                                   // Format where
    );
    $affected = $wpdb->rowsaffected;
    
    // DELETE
    $wpdb->delete(
        $wpdb->posts,
        ['ID' => 1],
        ['%d']
    );
    
    // Requête directe
    $wpdb->query("DELETE FROM {$wpdb->posts} WHERE posttype = 'trash'");
    
    // Préfixe des tables
    $tablename = $wpdb->prefix . 'matablecustom';
    
    // Créer table custom
    $charsetcollate = $wpdb->getcharsetcollate();
    $sql = "CREATE TABLE $tablename (
        id mediumint(9) NOT NULL AUTOINCREMENT,
        name varchar(100) NOT NULL,
        email varchar(100) NOT NULL,
        createdat datetime DEFAULT CURRENTTIMESTAMP NOT NULL,
        PRIMARY KEY  (id)
    ) $charsetcollate;";
    
    requireonce ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta($sql);
    
    // Erreurs
    $wpdb->showerrors();
    $wpdb->printerror();
    $wpdb->lasterror;
    $wpdb->lastquery;
    

    Options API

    option('monoption', 'valeur', '', 'yes'); // yes = autoload
    $valeur = getoption('monoption', 'défaut');
    
    // Mettre à jour (crée si n'existe pas)
    updateoption('monoption', 'nouvelle valeur');
    
    // Supprimer
    deleteoption('monoption');
    
    // Options réseau (multisite)
    addsiteoption('monoption', 'valeur');
    getsiteoption('monoption', 'défaut');
    updatesiteoption('monoption', 'valeur');
    deletesiteoption('monoption');
    
    // Vérifier existence
    if (getoption('monoption') !== false) {
        // Option existe
    }
    

    Conditional Tags

    home();              // Page d'accueil du blog
    isfrontpage();        // Page d'accueil du site
    issingle();            // Article seul
    issingle(123);         // Article ID 123
    issingle('hello');     // Article slug "hello"
    ispage();              // Page
    ispage(456);           // Page ID 456
    ispage('contact');     // Page slug "contact"
    ispagetemplate('template-custom.php');
    isarchive();           // Archive
    iscategory();          // Archive catégorie
    iscategory('news');    // Catégorie "news"
    istag();               // Archive tag
    istag('featured');     // Tag "featured"
    istax();               // Archive taxonomie custom
    istax('productcat');  // Taxonomie productcat
    isauthor();            // Archive auteur
    isauthor(1);           // Auteur ID 1
    isdate();              // Archive date
    isyear();              // Archive année
    ismonth();             // Archive mois
    isday();               // Archive jour
    istime();              // Archive heure
    issearch();            // Résultats recherche
    is404();               // Page 404
    isattachment();        // Page attachement
    issingular();          // Article ou page seule
    isposttypearchive('product');
    
    // Contexte
    isadmin();             // Backoffice
    isuserloggedin();    // Utilisateur connecté
    issticky();            // Article épinglé
    haspostthumbnail();   // A une image mise en avant
    hasexcerpt();          // A un extrait
    hastag('news');        // A le tag "news"
    hascategory('tech');   // A la catégorie "tech"
    hasterm('blue', 'color'); // A le terme "blue" de taxonomie "color"
    ismultiauthor();      // Site avec plusieurs auteurs
    ispaged();             // Page paginée (page 2+)
    incategory('news');    // Dans catégorie "news"
    
    // Template
    ismainquery();        // Dans requête principale
    isactivesidebar('sidebar-1'); // Sidebar active
    
    // Multisite
    ismultisite();
    ismainsite();
    

    Shortcodes

    shortcode() {
        return '

    Contenu du shortcode

    '; } addshortcode('monshortcode', 'monshortcode'); // Utilisation: [monshortcode] // Avec attributs function shortcodebouton($atts) { $atts = shortcodeatts([ 'url' => '#', 'texte' => 'Cliquez ici', 'couleur' => 'blue', ], $atts, 'bouton'); return sprintf( '%s', escurl($atts['url']), escattr($atts['couleur']), eschtml($atts['texte']) ); } addshortcode('bouton', 'shortcodebouton'); // Utilisation: [bouton url="https://example.com" texte="Voir plus" couleur="red"] // Avec contenu function shortcodebox($atts, $content = null) { $atts = shortcodeatts([ 'titre' => '', 'couleur' => 'blue', ], $atts); $content = doshortcode($content); // Parse shortcodes imbriqués $output = '
    '; if ($atts['titre']) { $output .= '

    ' . eschtml($atts['titre']) . '

    '; } $output .= '
    ' . $content . '
    '; $output .= '
    '; return $output; } addshortcode('box', 'shortcodebox'); // Utilisation: [box titre="Mon titre" couleur="red"]Contenu[/box] // Retirer shortcode removeshortcode('monshortcode'); // Vérifier si shortcode existe if (shortcodeexists('monshortcode')) { // ... } // Parser shortcodes dans texte $content = doshortcode('[monshortcode]'); // Échapper shortcodes (afficher sans exécuter) // [[monshortcode]] affichera [monshortcode]

    Internationalisation (i18n)

    ('Texte à traduire', 'mon-theme');
    e('Texte affiché directement', 'mon-theme');
    eschtml('Texte échappé HTML', 'mon-theme');
    eschtmle('Texte échappé et affiché', 'mon-theme');
    escattr('Texte pour attribut', 'mon-theme');
    
    // Contexte (pour différencier même texte)
    x('Post', 'nom', 'mon-theme');
    x('Post', 'verbe', 'mon-theme');
    
    // Pluriel
    n('1 commentaire', '%s commentaires', $nombre, 'mon-theme');
    printf(n('1 commentaire', '%s commentaires', $count, 'mon-theme'), $count);
    
    // Contexte + pluriel
    nx('1 produit', '%s produits', $nombre, 'e-commerce', 'mon-theme');
    
    // Variables
    sprintf(('Bonjour %s', 'mon-theme'), $nom);
    
    // Charger traductions (functions.php)
    function monthemeloadtextdomain() {
        loadthemetextdomain('mon-theme', gettemplatedirectory() . '/languages');
    }
    addaction('aftersetuptheme', 'monthemeloadtextdomain');
    
    // Pour plugin
    loadplugintextdomain('mon-plugin', false, dirname(pluginbasename(FILE_)) . '/languages');
    
    // Structure fichiers traduction
    // mon-theme/languages/frFR.po
    // mon-theme/languages/frFR.mo
    // mon-theme/languages/enUS.po
    // mon-theme/languages/enUS.mo
    

    Sécurité WordPress

    Nonces

    createnonce('mon-action');
    
    // Champ nonce dans formulaire
    wpnoncefield('mon-action', 'monnoncefield');
    
    // URL avec nonce
    $url = wpnonceurl('admin.php?page=ma-page&action=supprimer', 'supprimer-action');
    
    // Vérifier nonce
    if (isset($POST['monnoncefield']) && wpverifynonce($POST['monnoncefield'], 'mon-action')) {
        // Traitement sécurisé
    }
    
    // Vérifier nonce dans URL
    if (isset($GET['wpnonce']) && wpverifynonce($GET['wpnonce'], 'supprimer-action')) {
        // OK
    }
    
    // AJAX nonce
    checkajaxreferer('mon-action', 'nonce');
    
    // Admin nonce
    checkadminreferer('mon-action', 'monnoncefield');
    

    Sanitization et Validation

    textfield($POST['champ']);       // Texte simple
    sanitizeemail($POST['email']);             // Email
    sanitizeurl($POST['url']);                 // URL
    sanitizetitle($POST['titre']);             // Titre/slug
    sanitizekey($POST['cle']);                 // Clé (lettres, chiffres, tirets)
    sanitizehtmlclass($POST['classe']);       // Classe CSS
    sanitizetextareafield($POST['texte']);    // Textarea
    
    // Validation
    isemail($email);                            // Email valide
    filtervar($email, FILTERVALIDATEEMAIL);
    filtervar($url, FILTERVALIDATEURL);
    filtervar($int, FILTERVALIDATEINT);
    
    // Échappement sortie
    eschtml($text);                             // Texte HTML
    escattr($text);                             // Attribut
    escurl($url);                               // URL
    escjs($text);                               // JavaScript
    esctextarea($text);                         // Textarea
    
    // Données complexes
    wpkses($html, $allowedtags);              // HTML avec tags autorisés
    wpksespost($html);                        // HTML autorisé dans posts
    
    // Exemple complet
    if (isset($POST['submit']) && wpverifynonce($POST['wpnonce'], 'mon-formulaire')) {
        $nom = sanitizetextfield($POST['nom']);
        $email = sanitizeemail($POST['email']);
        $url = escurlraw($POST['url']);
        $message = sanitizetextareafield($POST['message']);
    
        if (isemail($email)) {
            // Traiter données
        }
    }
    

    Capabilities (Capacités)

    usercan('editposts')) {
        // Utilisateur peut éditer posts
    }
    
    // Capacités courantes
    'read'                  // Lecture
    'editposts'            // Éditer ses posts
    'editothersposts'     // Éditer posts des autres
    'publishposts'         // Publier posts
    'deleteposts'          // Supprimer ses posts
    'deleteothersposts'   // Supprimer posts des autres
    'manageoptions'        // Gérer options (admin)
    'managecategories'     // Gérer catégories
    'uploadfiles'          // Upload fichiers
    'editthemeoptions'    // Modifier thème
    'installplugins'       // Installer plugins
    'activateplugins'      // Activer plugins
    'editusers'            // Éditer utilisateurs
    'deleteusers'          // Supprimer utilisateurs
    
    // Par post type
    currentusercan('editpost', $postid);
    currentusercan('deletepost', $postid);
    
    // Obtenir utilisateur courant
    $currentuser = wpgetcurrentuser();
    echo $currentuser->userlogin;
    echo $currentuser->useremail;
    echo $currentuser->ID;
    
    // Vérifier rôle
    if (inarray('administrator', $currentuser->roles)) {
        // Est admin
    }
    

    Performance et optimisation

    transient('madonnee', $valeur, 12  HOURINSECONDS);
    $data = gettransient('madonnee');
    if ($data === false) {
        // Calculer/récupérer données
        $data = fonctioncouteuse();
        settransient('madonnee', $data, 12  HOURINSECONDS);
    }
    deletetransient('madonnee');
    
    // Object cache
    wpcacheset('macle', $valeur, 'mongroupe', 3600);
    $data = wpcacheget('macle', 'mongroupe');
    wpcachedelete('macle', 'mongroupe');
    wpcacheflush(); // Vider tout
    
    // Désactiver updates pour tests
    define('AUTOMATICUPDATERDISABLED', true);
    define('WPAUTOUPDATECORE', false);
    
    // Désactiver révisions
    define('WPPOSTREVISIONS', false);
    // Ou limiter
    define('WPPOSTREVISIONS', 3);
    
    // Augmenter memory limit
    define('WPMEMORYLIMIT', '256M');
    define('WPMAXMEMORYLIMIT', '512M');
    
    // Debug
    define('WPDEBUG', true);
    define('WPDEBUGLOG', true);
    define('WPDEBUGDISPLAY', false);
    
    // Heartbeat API (réduit charge serveur)
    addaction('init', function() {
        wpderegister_script('heartbeat');
    });
    

    Version: WordPress 6.4+ | Documentation:** developer.wordpress.org

    Une remarque, un retour ?

    Cet article est vivant — corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.