WP24Horas
PARCEIRO RECOMENDADO Vai colocar um WordPress no ar? Comece com uma hospedagem que acompanha o seu projeto. Conhecer a HostGator link patrocinado

Desenvolvimento e Programação

Como adaptar um plugin existente para a WordPress Abilities API

Por Asllan Maciel6 min de leitura
Plugin WordPress existente sendo adaptado com segurança para uma Ability usada por agentes de IA

Adicionar a Abilities API a um plugin existente não começa com wp_register_ability(). O primeiro trabalho é entender o que o plugin já faz, separar política de implementação e decidir qual operação é segura para agentes descobrirem ou executarem.

Neste estudo prático, migramos o plugin WP24 — Links externos em nova aba da versão 1.0.0 para a 1.1.0. Ele já percorria links do site público e aplicava target="_blank", noopener e noreferrer a destinos externos. A nova versão preserva esse comportamento e expõe a política como a Ability wp24/external-links-policy.

O exemplo foi validado no WordPress 6.8.3, 7.0.2 e 7.1-RC1 com PHP 8.3. Isso permite demonstrar tanto a integração com a Abilities API quanto um fallback seguro para versões anteriores.

Comece pelo inventário, não pelo registro

O plugin original tinha uma operação principal: imprimir um JavaScript no rodapé e alterar links externos no navegador. Dentro desse fluxo havia decisões de negócio escondidas como valores fixos:

  • protocolos aceitos: HTTP e HTTPS;
  • destino: nova aba;
  • relações obrigatórias: noopener e noreferrer;
  • seletor ignorado: barra administrativa;
  • observação de links adicionados dinamicamente.

Esses valores formavam uma política, mas estavam acoplados à implementação JavaScript. Copiá-los para uma Ability criaria duas fontes de verdade. A primeira mudança, portanto, foi extrair a política para uma função PHP.

Refatoração de um plugin WordPress para compartilhar uma política entre o navegador e uma Ability para agentes de IA
A política sai do JavaScript acoplado e vira uma fonte única consumida pelo navegador e pela Ability.

Classifique a operação antes de expô-la

Nem toda função do plugin deve virar Ability. Para este caso, avaliamos três candidatas:

Candidata Risco Decisão
retornar a política pública leitura, sem dado sensível implementar
classificar uma URL enviada pelo agente entrada externa e diferenças de parser adiar
reescrever conteúdo armazenado escrita e efeito colateral não implementar neste ciclo

A operação escolhida não aceita URL, não faz requisição de rede e não grava nada. Ela apenas descreve um comportamento que qualquer visitante já consegue observar no HTML e no JavaScript públicos.

Extraia uma fonte única de verdade

A política passou a ser retornada por uma função pura:


function wp24_external_links_policy(): array {
    return array(
        'enabled_public_site'      => true,
        'allowed_protocols'        => array( 'http:', 'https:' ),
        'external_target'          => '_blank',
        'rel_tokens'               => array( 'noopener', 'noreferrer' ),
        'ignored_selectors'        => array( '#wpadminbar' ),
        'observes_dynamic_content' => true,
    );
}

O front-end recebe essa estrutura com wp_json_encode():


$policy = wp24_external_links_policy();
?>
<script id="wp24-external-links">
(() => {
  const policy = <?php echo wp_json_encode(
      $policy,
      JSON_UNESCAPED_SLASHES
  ); ?>;
  const allowedProtocols = new Set(policy.allowed_protocols);
  // A rotina existente usa os valores da política.
})();
</script>
<?php

Agora o JavaScript e a Ability descrevem exatamente a mesma regra. Alterar rel_tokens em PHP modifica os dois consumidores.

Registre uma categoria compatível

O plugin continua funcionando em versões anteriores à Abilities API. Por isso, os callbacks verificam se as funções existem:


function wp24_external_links_register_ability_category(): void {
    if ( ! function_exists( 'wp_register_ability_category' ) ) {
        return;
    }

    wp_register_ability_category(
        'wp24-site-behavior',
        array(
            'label' => 'Comportamento do site',
            'description' => 'Políticas públicas aplicadas ao site.',
        )
    );
}
add_action(
    'wp_abilities_api_categories_init',
    'wp24_external_links_register_ability_category'
);

Adicionar callbacks a hooks inexistentes não causa erro no WordPress. Quando a versão não dispara esses hooks, o comportamento antigo permanece ativo.

Registre a Ability com contrato restrito

A Ability não recebe entrada e declara toda a forma da saída:


wp_register_ability(
    'wp24/external-links-policy',
    array(
        'label'               => 'Política de links externos',
        'description'         => 'Retorna a política pública usada pelo site para abrir links externos com segurança.',
        'category'            => 'wp24-site-behavior',
        'input_schema'        => array(),
        'output_schema'       => array(
            'type'                 => 'object',
            'additionalProperties' => false,
            'required'             => array(
                'enabled_public_site',
                'allowed_protocols',
                'external_target',
                'rel_tokens',
                'ignored_selectors',
                'observes_dynamic_content',
            ),
            'properties'           => array(
                'enabled_public_site' => array( 'type' => 'boolean' ),
                'allowed_protocols'   => array(
                    'type'  => 'array',
                    'items' => array( 'type' => 'string' ),
                ),
                'external_target'     => array( 'type' => 'string' ),
                'rel_tokens'          => array(
                    'type'  => 'array',
                    'items' => array( 'type' => 'string' ),
                ),
                'ignored_selectors'   => array(
                    'type'  => 'array',
                    'items' => array( 'type' => 'string' ),
                ),
                'observes_dynamic_content' => array(
                    'type' => 'boolean',
                ),
            ),
        ),
        'execute_callback'    => 'wp24_external_links_policy',
        'permission_callback' => '__return_true',
        'meta'                => array(
            'show_in_rest' => true,
            'annotations'  => array(
                'readonly'    => true,
                'destructive' => false,
                'idempotent'  => true,
            ),
        ),
    )
);

additionalProperties => false impede que o callback acrescente campos não documentados sem que o contrato seja revisado.

Por que a permissão é pública neste caso

Usar __return_true exige uma justificativa, não conveniência. Aqui a saída reproduz uma política já entregue a visitantes anônimos no JavaScript do site. Não há opções privadas, lista de plugins, dados de usuários ou conteúdo editorial.

Se a Ability retornasse configurações administrativas, domínios internos ou regras ainda não publicadas, a permissão deveria exigir uma capability apropriada.

O erro que os testes encontraram

Na primeira implementação, show_in_rest foi colocado no nível principal dos argumentos. A Ability existia e executava em PHP, mas o endpoint REST respondia rest_ability_not_found.

O local correto é dentro de meta:


'meta' => array(
    'show_in_rest' => true,
    'annotations'  => array(
        'readonly'    => true,
        'destructive' => false,
        'idempotent'  => true,
    ),
),

Esse teste demonstra por que verificar apenas wp_get_ability() é insuficiente quando a integração depende de REST. Registro, execução PHP e exposição externa são critérios separados.

Matriz de compatibilidade executada

WordPress Resultado
6.8.3 plugin ativo, política e JavaScript preservados, Abilities API ausente sem fatal
7.0.2 Ability registrada, saída aprovada pelo schema e REST HTTP 200
7.1-RC1 Ability registrada, saída aprovada pelo schema e REST HTTP 200

Saída observada no 7.0.2 e no 7.1-RC1:


{
  "enabled_public_site": true,
  "allowed_protocols": ["http:", "https:"],
  "external_target": "_blank",
  "rel_tokens": ["noopener", "noreferrer"],
  "ignored_selectors": ["#wpadminbar"],
  "observes_dynamic_content": true
}

Os testes também capturaram o script renderizado e confirmaram a presença da política serializada e de noopener. Todos os containers, redes e volumes temporários foram removidos depois da validação.

Checklist para adaptar seu plugin

  1. inventarie funções e efeitos colaterais;
  2. separe política de implementação;
  3. comece por uma operação pequena e somente leitura;
  4. rejeite candidatos que ampliem o acesso sem benefício claro;
  5. defina namespace, nome e descrição orientados a tarefa;
  6. use schemas fechados e tipos específicos;
  7. justifique a permission_callback com base nos dados;
  8. coloque show_in_rest dentro de meta quando necessário;
  9. trate Abilities ausentes sem quebrar versões anteriores;
  10. teste registro PHP, execução, REST e regressão do comportamento antigo;
  11. valide também a negação quando a operação for protegida;
  12. versione e documente a mudança.

Download do plugin do estudo

Baixe o WP24 External Links 1.1.0. O pacote contém o plugin e o README, sem ambiente Docker, credenciais ou arquivos de teste.

SHA-256 do pacote validado:


FCE2B994B1BE11B6D8723765320F6AC4623F445083AD748F7CC6D8D201611C5A

Próximo passo

Depois de migrar uma operação real e conectá-la a um agente, o próximo nível é desenhar a arquitetura de produção: isolamento do bridge, gestão de secrets, allowlists por ambiente, observabilidade, limites de execução e resposta a incidentes.

Fontes oficiais

Sobre o autor

Asllan Maciel

Asllan Maciel, Fundador do WP24Horas, Consultor de Marketing Digital e amante do Empreendedorismo Digital. Tem um caso de amor com o WordPress.