# Settings API WordPress : construire une page de réglages sans réinventer la roue

> register_setting, add_settings_section et add_settings_field permettent de créer une page d'options propre, sécurisée et compatible multisite, sans formulaire fait maison.

- Auteur : Clément Hadrot
- Publié le : 2020-08-25
- Mis à jour le : 2020-08-25
- Catégorie : Extensions
- URL : https://wpmoderne.dev.wordpress-developpement.fr/extensions/settings-api-page-reglages/

## L’essentiel

- register_setting gère nonce, capability et sanitisation
- Les sections et champs restent réutilisables
- Compatible avec le customizer et le réseau multisite

Beaucoup d'extensions WordPress affichent encore une page de réglages construite à la main : un formulaire HTML, un traitement du `$_POST` directement dans le fichier d'administration, et une sauvegarde via `update_option()` sans vérification de nonce ni de capability. Cela fonctionne, jusqu'au jour où un audit de sécurité ou un test avec WordPress multisite révèle les failles de cette approche artisanale.

La Settings API, présente depuis WordPress 2.7, résout ce problème depuis longtemps mais reste sous-utilisée. Elle prend en charge la génération du nonce, la vérification de la capability, la sanitisation des valeurs et l'affichage des erreurs de validation, pour un coût d'apprentissage finalement modeste.

## Les trois briques de la Settings API

Trois fonctions suffisent à construire n'importe quelle page de réglages :

- `register_setting()` déclare une option, sa sanitisation et son groupe
- `add_settings_section()` déclare un regroupement visuel de champs
- `add_settings_field()` déclare un champ individuel, avec son callback d'affichage

```
add_action( 'admin_init', function () {
    register_setting(
        'acme_options_group',      // groupe d'options
        'acme_api_key',            // nom de l'option en base
        [
            'type'              => 'string',
            'sanitize_callback' => 'sanitize_text_field',
            'default'           => '',
        ]
    );

    add_settings_section(
        'acme_section_api',
        __( 'Connexion à l\'API', 'acme' ),
        function () {
            echo '' . esc_html__( 'Renseignez votre clé d\'API personnelle.', 'acme' ) . '';
        },
        'acme-page'
    );

    add_settings_field(
        'acme_api_key_field',
        __( 'Clé API', 'acme' ),
        function () {
            $value = get_option( 'acme_api_key', '' );
            printf(
                '',
                esc_attr( $value )
            );
        },
        'acme-page',
        'acme_section_api'
    );
} );
```

## La page d'administration qui affiche le tout

La page elle-même reste très courte : les fonctions `settings_fields()` et `do_settings_sections()` génèrent respectivement les champs cachés (nonce, action, option_page) et l'ensemble des sections déclarées.

```
add_action( 'admin_menu', function () {
    add_options_page(
        __( 'Réglages Acme', 'acme' ),
        'Acme',
        'manage_options',
        'acme-page',
        function () {
            echo '' . esc_html__( 'Réglages Acme', 'acme' ) . '';
            settings_fields( 'acme_options_group' );
            do_settings_sections( 'acme-page' );
            submit_button();
            echo '';
        }
    );
} );
```

C'est `options.php`, un fichier interne à WordPress, qui traite la soumission : vérification du nonce généré par `settings_fields()`, contrôle de la capability associée au groupe d'options, sanitisation via le `sanitize_callback` déclaré, puis redirection vers la page d'origine avec un message de confirmation. Aucune de ces étapes n'est à écrire soi-même.

> L'essentiel à retenir : register_setting gère nonce, capability et sanitisation ; Les sections et champs restent réutilisables ; Compatible avec le customizer et le réseau multisite

## Sanitiser correctement selon le type de donnée

Le `sanitize_callback` mérite d'être choisi avec soin selon la nature de la donnée :

| Type de champ | Fonction de sanitisation adaptée |
| --- | --- |
| Texte simple | sanitize_text_field |
| Adresse e-mail | sanitize_email |
| URL | esc_url_raw |
| Nombre entier | absint |
| Contenu HTML limité | wp_kses_post |
| Case à cocher | fonction personnalisée retournant un booléen strict |

Pour une case à cocher, la sanitisation par défaut ne suffit pas toujours : un callback maison garantit une valeur propre en base plutôt qu'une chaîne `"on"` ou une valeur vide selon les navigateurs.

```
register_setting( 'acme_options_group', 'acme_notifications', [
    'type'              => 'boolean',
    'sanitize_callback' => function ( $value ) {
        return (bool) $value;
    },
    'default' => false,
] );
```

## Valider et afficher une erreur

Au-delà de la sanitisation, la Settings API permet une vraie validation avec message d'erreur via `add_settings_error()`, appelée depuis le `sanitize_callback` :

```
register_setting( 'acme_options_group', 'acme_api_key', [
    'sanitize_callback' => function ( $value ) {
        $value = sanitize_text_field( $value );
        if ( strlen( $value ) < 20 ) {
            add_settings_error(
                'acme_api_key',
                'acme_api_key_invalide',
                __( 'La clé API semble trop courte, vérifiez votre copier-coller.', 'acme' )
            );
            return get_option( 'acme_api_key' ); // on conserve l'ancienne valeur
        }
        return $value;
    },
] ) );
```

Cette approche évite d'enregistrer une valeur manifestement invalide tout en informant l'utilisateur de façon native, avec le même style visuel que les messages d'erreur du cœur de WordPress.

> Sur les projets où l'on reprend une extension existante, remplacer un formulaire fait maison par la Settings API est souvent le chantier de sécurité le plus rentable : quelques heures de travail suppriment une classe entière de failles CSRF potentielles.

## Compatibilité multisite et REST

Un avantage moins connu : une option déclarée avec `register_setting()` et l'argument `show_in_rest` devient automatiquement disponible via l'endpoint REST `/wp/v2/settings`, sous réserve que l'utilisateur ait la capability `manage_options`. Cela évite d'écrire un contrôleur REST personnalisé pour de simples options globales.

```
register_setting( 'acme_options_group', 'acme_api_key', [
    'type'         => 'string',
    'show_in_rest' => true,
    'default'      => '',
] );
```

## En résumé

La Settings API demande un peu plus de code qu'un formulaire artisanal pour un champ unique, mais elle devient rentable dès la deuxième option et incontournable au-delà de cinq. Nonce, capability, sanitisation, validation et exposition REST sont pris en charge par le cœur de WordPress : autant de code que vous n'avez pas à maintenir ni à sécuriser vous-même.
