Skip to content
⌨️ Como adicionar a sua própria secção à página de definições do WordPress

⌨️ Como adicionar a sua própria secção à página de definições do WordPress

As páginas de definições padrão do WordPress, «General», «Reading», «Discussion», cobrem as necessidades básicas de um site. Mas assim que escreve um plugin ou personaliza um tema para um cliente, o conjunto de campos integrado deixa de ser suficiente. Precisa de um bloco com as suas próprias opções: uma chave de API, texto de rodapé, um alternador de modo.

Criar uma página de administração separada para apenas dois campos é um exagero. É muito mais limpo adicionar a sua própria secção a uma página de definições existente, exatamente onde residem as opções padrão do WordPress. A API de Definições fornece uma única função para isto: add_settings_section.

Vamos percorrer a sua sintaxe, parâmetros e construir um exemplo funcional com uma secção e um campo, desde o hook admin_init até à saída no painel de administração. Sem abstrações desnecessárias: apenas o que pode copiar e executar por si mesmo.

💡 Visão geral rápida:

  • Defina a página de destino (general, reading, writing, discussion, media ou uma personalizada), vai precisar do seu slug no quarto parâmetro
  • Registe a secção via add_settings_section() no hook admin_init: forneça um ID, título e um callback para texto descritivo
  • Anexe campos à secção via add_settings_field() e guarde a própria opção via register_setting()
  • Chame do_settings_sections() no callback da página para páginas personalizadas, a secção será renderizada automaticamente

O que é a API de Definições e porque precisa dela

A API de Definições surgiu no WordPress 2.7 e permaneceu desde então a forma padrão de adicionar definições ao painel de administração. A ideia é simples: em vez de escrever manualmente um <form> e tratar o $_POST, descreve secções e campos através de funções, e o próprio WordPress renderiza a marcação, trata da gravação e verifica o nonce.

Os três pilares da API de Definições:

  • register_setting(), regista uma opção em wp_options;
  • add_settings_section(), cria um bloco (secção) com um título;
  • add_settings_field(), adiciona um campo específico a uma secção.

É o add_settings_section o responsável pelo «contentor», o bloco visual que agrupa vários campos sob um título comum na página de definições. Sem ele, simplesmente não há onde colocar os campos.

Sintaxe do add_settings_section

A assinatura da função é concisa, quatro parâmetros obrigatórios e um array opcional:

1add_settings_section(
2 string $id,
3 string $title,
4 callable $callback,
5 string $page,
6 array $args = array()
7);

A função não devolve nada. Regista a secção no array global $wp_settings_sections, de onde o WordPress a recupera quando do_settings_sections() é chamado na página de destino. Se chamar add_settings_section sem um do_settings_sections subsequente numa página personalizada, a secção silenciosamente não é renderizada.

Uma nuance importante: add_settings_section apenas descreve o bloco. Os campos em si são adicionados por chamadas separadas a add_settings_field, especificando o ID da secção no quinto parâmetro. Sem campos, a secção permanece um invólucro vazio, o que por vezes é útil para uma explicação textual, mas na prática quase sempre se coloca pelo menos um campo ao lado.

Parâmetros da função, o que passar

$id (string, obrigatório), o slug único da secção. Use letras minúsculas, números e underscores: my_plugin_main_section. Vai especificar este mesmo ID em add_settings_field para «anexar» o campo à secção, e ele também aparece no atributo HTML id da tag de invólucro.

$title (string, obrigatório), o título da secção que o administrador vê. É emitido como um <h2> dentro da página de definições. Escreva-o em linguagem clara para o administrador: «Настройки интеграции с CRM», e não my_plugin_crm_settings.

$callback (callable, obrigatório), o nome da função que ecoa o texto descritivo entre o título da secção e os campos. Assinatura: function my_callback($args), onde $args é um array com as chaves id, title e callback. Se não for necessária explicação, passe '__return_false'.

$page (string, obrigatório), o slug da página de definições onde a secção é adicionada. Páginas integradas do WordPress: general, reading, writing, discussion, media. Para uma página personalizada, o slug passado a add_options_page(). ⚠ As páginas misc e privacy foram removidas do núcleo (obsoletas), o WordPress redirecionará automaticamente miscgeneral, privacyreading, mas é melhor não depender deste comportamento.

$args (array, opcional, desde o WordPress 6.1.0), um array para personalizar o invólucro HTML da secção:

Chave

Tipo

Descrição

before_section

string

HTML inserido ANTES do conteúdo da secção. Recebe a classe da secção como %s

after_section

string

HTML após o conteúdo da secção. Não é emitido se a secção estiver vazia

section_class

string

Classe CSS para o invólucro da secção

O argumento $args só funciona quando do_settings_sections() é chamado. Se do_settings_fields() for usado por engano, o array é ignorado e before_section/after_section silenciosamente não têm efeito.

Exemplo prático: uma secção com um campo na página «General»

Vamos montar um snippet pronto a usar para o functions.php ou para o seu próprio plugin. O código adiciona uma secção «Definições do site cartão de visita» à página options-general.php com um campo de texto, por exemplo, para um número de telefone no rodapé.

1/**
2 * Adds a custom section and field to the «General» page.
3 */
4function sdstudio_add_visiting_card_section() {
5 // 1. Section
6 add_settings_section(
7 'visiting_card_section', // Section ID
8 'Visiting Card Settings', // Title
9 'sdstudio_visiting_card_section_cb', // Callback explanation
10 'general', // «General» page
11 array(
12 'before_section' => '<div class="visiting-card-wrapper">',
13 'after_section' => '</div>',
14 )
15 );
16
17 // 2. Field
18 add_settings_field(
19 'footer_phone', // Field ID
20 'Footer Phone Number', // Label
21 'sdstudio_footer_phone_field_cb', // Callback — renders <input>
22 'general', // Same page
23 'visiting_card_section' // Which section to attach to
24 );
25
26 // 3. Registering the option
27 register_setting( 'general', 'footer_phone' );
28}
29add_action( 'admin_init', 'sdstudio_add_visiting_card_section' );
30
31/**
32 * Explanatory text above the section fields.
33 */
34function sdstudio_visiting_card_section_cb( $args ) {
35 ?>
36 <p id="<?php echo esc_attr( $args['id'] ); ?>">
37 Contact details displayed in the site footer.
38 </p>
39 <?php
40}
41
42/**
43 * Renders a text input field.
44 */
45function sdstudio_footer_phone_field_cb() {
46 $value = get_option( 'footer_phone', '' );
47 printf(
48 '<input type="text" id="footer_phone" name="footer_phone" value="%s" class="regular-text" />',
49 esc_attr( $value )
50 );
51}

Depois de adicionar o código, vá ao painel de administração: Definições → Geral, e abaixo dos campos padrão verá a secção «Definições do site cartão de visita» com o campo «Telefone do rodapé». Guarde a página e o valor será escrito em wp_options.

O código é colocado no functions.php do tema ativo ou, mais corretamente, num plugin separado. Um plugin sobrevive a uma mudança de tema, enquanto o functions.php não. Se a secção só for necessária enquanto um tema específico estiver ativo, o functions.php é aceitável; em todos os outros casos, apenas um plugin.

O argumento $args: o que mudou no WordPress 6.1

Antes da versão 6.1, o add_settings_section tinha exatamente quatro parâmetros, e tinha de «retocar» o invólucro da secção via CSS pelo ID, ou manipular o buffer de saída. A partir da 6.1, foi adicionado um quinto parâmetro $args, e agora o enquadramento HTML é definido diretamente ao registar a secção:

  • before_section, um invólucro div ou um banner explicativo ANTES do conteúdo;
  • after_section, uma tag de fecho ou uma dica APÓS o conteúdo;
  • section_class, uma classe personalizada se a form-table padrão não for suficiente.

Um exemplo com um banner explicativo e uma classe personalizada:

1add_settings_section(
2 'api_keys_section',
3 'API Keys',
4 'sdstudio_api_keys_section_cb',
5 'general',
6 array(
7 'before_section' => '<div class="notice notice-info inline"><p>Store keys in wp-config.php, override here only.</p></div>',
8 'after_section' => '',
9 'section_class' => 'api-keys-section',
10 )
11);

O que é importante lembrar: after_section não é emitido se a secção estiver vazia, ou seja, quando não há campos registados dentro dela. Se está a contar com um </div> de fecho, certifique-se de que pelo menos um campo é adicionado via add_settings_field. E o mais importante: use do_settings_sections(), não do_settings_fields(), pois este último ignorará completamente os $args.

Antes de usar before_section / after_section, verifique a versão do WordPress; em sites anteriores à 6.1, passar o quinto parâmetro causará um erro fatal. Uma abordagem segura: envolva a chamada numa verificação global $wp_version ou use function_exists para verificar a presença dos hooks.

⁉️🤔 Perguntas frequentes

Posso saltar o add_settings_section e adicionar campos diretamente?

Formalmente, não. Os campos são registados via add_settings_field(), e o quinto parâmetro desta função requer um ID de secção. Se a secção não existir, o campo não será renderizado. Para um único campo, pode criar uma secção com um título vazio e um callback '__return_false', a secção ficará invisível e o campo funcionará.

Qual é a diferença entre add_settings_section e add_settings_field?

Uma secção é um contentor com um título e texto descritivo. Um campo é um elemento de entrada específico (input, select, checkbox) dentro de uma secção. Uma secção pode conter qualquer número de campos, todos agrupados sob um título e guardados com um único clique no botão «Guardar».

O que acontece se eu especificar um slug de página inexistente em $page?

A secção será registada em $wp_settings_sections, mas nunca será renderizada, pois o WordPress não sabe em que página a deve emitir. Não haverá erro, a secção simplesmente «ficará no ar». Verifique o slug: para páginas integradas é general / reading / writing / discussion / media; para as personalizadas, o slug exato de add_menu_page ou add_options_page.

Posso adicionar uma secção à página de outro plugin?

Sim, se souber o slug da página dele. Passe-o em $page e a secção aparecerá na página de definições do outro plugin. Mas esta é uma solução frágil: o autor do plugin pode mudar o slug numa atualização, e a sua secção «cairá». Use-a apenas para os seus próprios projetos ou quando não houver alternativas.

O que faz o hook admin_init e porque é que o add_settings_section é chamado nele?

O admin_init é disparado em cada pedido ao painel de administração ANTES de a página ser renderizada. Este é o momento certo para registar definições: secções e campos devem ser declarados antes de o WordPress começar a montar o formulário. Se chamar add_settings_section mais tarde, por exemplo, dentro do callback da página, a secção não entrará em $wp_settings_sections e não será exibida.

A sua própria secção ou uma página separada, o que escolher

Adicionar uma secção a general é mais simples: menos código, e o utilizador vê as definições no mesmo local onde edita o título do site. Mas quando há mais de três ou quatro opções, a secção incha a página padrão e confunde o administrador.

A regra é simples: uma ou duas opções, logicamente relacionadas com a página geral (telefone do rodapé, chave de API para comentários), use uma secção em general. Três ou mais opções, funcionalidade autónoma (um slider, integração CRM, uma grelha de preços), use uma página separada via add_options_page(). Em ambos os casos, o add_settings_section é o próprio bloco de construção onde a montagem começa.

Antes de copiar o código, certifique-se de que o WordPress está atualizado para a versão mais recente. O array $args, section_class e os invólucros before_section/after_section requerem pelo menos a 6.1, enquanto a função em si vive no núcleo desde a versão 2.7. Duas décadas de compatibilidade retroativa não são razão para permanecer num motor desatualizado.