Blog

Arquitetura de Hooks do WordPress: Ações vs. Filtros Explicados

A base de todo ótimo plugin. Aprenda como o PAGEnza AI usa hooks e filtros para criar código de fácil manutenção e escalável.

Todo plugin do WordPress faz uma de duas coisas: ele executa código em um momento específico (ação) ou modifica um valor antes que ele seja usado (filtro). É só isso. Todo o ecossistema de plugins do WordPress é construído sobre essa distinção.

Entender a diferença — e quando usar cada um — é o que separa plugins que funcionam de plugins que causam problemas.

Ações: fazer algo em um ponto no tempo

Um hook de ação é um sinal que o WordPress (ou outro plugin) envia em um momento específico. Você anexa uma função a esse sinal, e sua função é executada quando o sinal é disparado.

add_action( 'wp_enqueue_scripts', 'my_plugin_load_assets' );

function my_plugin_load_assets() {
    wp_enqueue_style( 'my-plugin', plugin_dir_url( __FILE__ ) . 'style.css' );
    wp_enqueue_script( 'my-plugin', plugin_dir_url( __FILE__ ) . 'script.js', ['jquery'], '1.0', true );
}

wp_enqueue_scripts é disparado quando o WordPress está se preparando para carregar os assets para o front-end. Enganchar nele é a maneira correta de carregar CSS e JS — não de inserir tags <script> diretamente em templates.

Ações comuns que você usará constantemente:

  • init — executa cedo, bom para registrar tipos de post e taxonomias
  • wp_enqueue_scripts — carregar assets do front-end
  • admin_enqueue_scripts — carregar assets do admin
  • save_post — executa quando um post é salvo, bom para processar campos personalizados
  • wp_ajax_{action} — lidar com requisições AJAX de usuários autenticados
  • wp_ajax_nopriv_{action} — lidar com AJAX de usuários não logados

Filtros: modificar um valor antes que ele seja usado

Um hook de filtro lhe dá um valor, permite que você o modifique e espera que você retorne a versão modificada. O WordPress então usa seu valor modificado em vez do original.

add_filter( 'the_content', 'my_plugin_append_cta' );

function my_plugin_append_cta( $content ) {
    if ( ! is_single() ) {
        return $content;
    }
    $cta = '<div class="post-cta">Pronto para experimentar o PAGEnza? <a href="#">Comece grátis →</a></div>';
    return $content . $cta;
}

A regra crítica: sempre retorne algo de um filtro. Se você esquecer o return, o valor se tornará nulo e você terá quebrado o que quer que estivesse usando-o.

Filtros comuns:

  • the_content — o conteúdo do post antes da exibição
  • the_title — o título do post
  • wp_nav_menu_items — HTML do menu de navegação
  • upload_mimes — tipos de upload de arquivo permitidos
  • plugin_action_links_{plugin-file} — links mostrados na página de lista de plugins

Como o PAGEnza AI usa hooks

Quando o Plugin Builder gera um plugin, ele estrutura o código em torno de uma classe com métodos anexados a hooks no construtor. Esse padrão evita colisões de nomes de funções globais e mantém o código organizado.

class My_Plugin {
    public function __construct() {
        add_action( 'init', [ $this, 'register_post_type' ] );
        add_action( 'wp_enqueue_scripts', [ $this, 'load_assets' ] );
        add_filter( 'the_content', [ $this, 'append_content' ] );
    }

    public function register_post_type() { /* ... */ }
    public function load_assets() { /* ... */ }
    public function append_content( $content ) {
        // sempre retorne
        return $content;
    }
}

new My_Plugin();

A verificação de segurança verifica especificamente que os manipuladores AJAX incluem uma verificação de nonce e uma verificação de capacidade antes de fazer qualquer coisa:

add_action( 'wp_ajax_my_action', [ $this, 'handle_ajax' ] );

public function handle_ajax() {
    // Segurança: verificar nonce
    check_ajax_referer( 'my_nonce_action', 'nonce' );

    // Segurança: verificar permissões
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Permissões insuficientes', 403 );
    }

    // Agora é seguro processar
    $data = sanitize_text_field( $_POST['data'] ?? '' );
    wp_send_json_success( [ 'result' => $data ] );
}

A falta de um desses é sinalizada como um problema de segurança e impede o lançamento do plugin.

Prioridade e a fila de hooks

Quando várias funções são anexadas ao mesmo hook, elas são executadas em ordem de prioridade (número menor = executa primeiro). A prioridade padrão é 10.

add_action( 'init', 'runs_first', 5 );
add_action( 'init', 'runs_second', 10 );   // padrão
add_action( 'init', 'runs_last', 20 );

Isso importa quando seu plugin precisa ser executado antes ou depois do código de outro plugin. Se você está modificando algo que outro plugin também modifica, a prioridade controla quem vence.

Um padrão comum: se você estiver substituindo um filtro de tema, use a prioridade 20 ou superior para garantir que você seja executado após o código do tema.

Removendo hooks

Você pode remover um hook que outra pessoa adicionou — incluindo hooks de tema e plugin:

remove_action( 'wp_head', 'wp_generator' );  // remove a versão do WP do <head>
remove_filter( 'the_content', 'wpautop' );   // remove a quebra automática de parágrafo

O detalhe: você só pode remover um hook se chamar remove_action/remove_filter depois que o add_action/add_filter original foi executado. Isso geralmente significa enganchar sua remoção em uma ação posterior.