WordPress 7.0 e PHP moderno na prática: 6 recursos novos aplicados neste site
Semana passada eu parei tudo e fiz uma pergunta desconfortável para o meu próprio site: quanto do WordPress e do PHP modernos eu estou realmente usando? A resposta honesta era “menos do que eu recomendo aos clientes”. Então apliquei no tema da Logup, em produção, seis recursos recentes do WordPress (6.8 até o 7.0, que roda aqui) e do PHP — e este post mostra exatamente o que mudou, com código de verdade, e o que cada mudança entrega em performance, robustez e manutenção.
Eu sou o Filipe, fundador da Logup Digital, desenvolvedor full-stack há mais de 12 anos. O contexto: o site que você está lendo roda um tema próprio, sem page builder, num WordPress 7.0.4 com PHP 8.1. Tudo abaixo está no ar agora — não é lista de tendência, é changelog.
1. Navegação instantânea com Speculative Loading
Desde o WordPress 6.8 o core imprime regras da Speculation Rules API: uma tag <script type="speculationrules"> que instrui o navegador a carregar páginas antes do clique. O padrão do core é conservador (prefetch no início do clique). Eu subi o nível para prerender com gatilho no hover:
add_filter( 'wp_speculation_rules_configuration', static function ( $config ) {
if ( is_array( $config ) ) {
$config['mode'] = 'prerender';
$config['eagerness'] = 'moderate';
}
return $config;
} );
Resultado prático: ao pousar o mouse (ou o dedo, no toque) sobre um link do blog, o navegador já renderiza a próxima página em segundo plano. O clique vira uma troca de tela instantânea. Sem plugin, sem JavaScript meu — e navegador sem suporte simplesmente ignora a tag.
Só que há uma pegadinha que quase ninguém comenta: página pré-renderizada executa JavaScript. Meu tracking first-party (que decide quais posts merecem investimento) contaria uma visita a cada hover — visita fantasma, métrica podre, decisão errada. A solução tem três linhas:
if (document.prerendering) {
document.addEventListener('prerenderingchange', fireView, { once: true });
} else {
fireView();
}
A visita só conta quando o visitante de fato ativa a página. Também excluí a página de contato da especulação, via wp_speculation_rules_href_exclude_paths. Se você usa GTM com pixels de conversão, confira isso hoje: há relatos documentados de “ghost visits” em sites WordPress 6.8+ exatamente por falta dessa guarda.
2. HTML API: aposentando regex que mexia em HTML
Aqui existe uma regra de negócio inegociável: o site nunca abre conversa de WhatsApp por conta própria — todo botão pede o número do visitante e quem chama sou eu. Posts antigos tinham links wa.me no corpo, e um filtro os reescrevia para o gatilho de captura usando expressão regular sobre o HTML.
Regex sobre HTML funciona até o dia em que não funciona: aspas simples, atributos em outra ordem, maiúsculas. Desde o WordPress 6.2 existe a HTML API, um parser de verdade dentro do core. O filtro novo:
$processor = new WP_HTML_Tag_Processor( $html );
while ( $processor->next_tag( 'a' ) ) {
$href = (string) $processor->get_attribute( 'href' );
if ( ! preg_match( '#^https?://(?:wa.me|api.whatsapp.com)/#i', $href ) ) {
continue;
}
$processor->set_attribute( 'href', $contact );
$processor->set_attribute( 'data-logup-capture', 'conteudo' );
$processor->remove_attribute( 'target' );
$processor->remove_attribute( 'rel' );
}
$html = $processor->get_updated_html();
O parser entende o markup como o navegador entende. O HTML nunca sai corrompido, e a regra mais importante do meu funil ficou à prova de edge case. Se o seu tema ou plugin faz preg_replace em cima de conteúdo HTML, essa é provavelmente a migração de melhor custo-benefício do WordPress moderno.
3. Interactivity API: o menu mobile virou declarativo
A Interactivity API é o framework reativo oficial do core (WordPress 6.5+), e a parte que pouca gente sabe: funciona em tema clássico, sem Gutenberg e sem build. O comportamento sai do JavaScript imperativo e vai para o próprio HTML, em diretivas:
<header class="navbar" data-wp-interactive="logup/menu"
data-wp-class--is-open="state.menuOpen">
<button data-wp-on--click="actions.toggle"
data-wp-bind--aria-expanded="state.menuOpen"
data-wp-bind--aria-label="state.menuLabel">…</button>
<div class="mobile-menu" inert
data-wp-bind--inert="!state.menuOpen">…</div>
</header>
E o estado vive num módulo ES de vinte e poucas linhas:
import { store } from "@wordpress/interactivity";
const { state } = store("logup/menu", {
state: {
get menuLabel() {
return state.menuOpen ? "Fechar menu" : "Abrir menu";
},
},
actions: {
toggle() {
state.menuOpen = !state.menuOpen;
},
},
});
O import é resolvido pelo import map que o próprio WordPress imprime — Script Modules API, também do core. Zero webpack, zero node_modules no servidor. As ~20 linhas antigas de classList, aria-expanded e malabarismo de tabindex viraram atributos que qualquer pessoa lê no template. De bônus, troquei o truque de tabindex="-1" link a link pelo atributo nativo inert, que tira o menu fechado da navegação por teclado e dos leitores de tela de uma vez.
4. Abilities API: o site descrito para agentes de IA
Essa é a mais estratégica. O WordPress 6.9 introduziu (e o 7.0 consolidou) a Abilities API: um registro padronizado do que o site sabe fazer — cada “ability” declara entrada e saída em JSON Schema, quem pode executar e como. É a fundação que o core construiu para a era dos agentes de IA e do MCP.
Registrei a primeira ability do site: um snapshot do meu funil de leads (visitas do dia, leads, estágios, pipeline), que vira endpoint REST autenticado e autodescritivo:
wp_register_ability( 'logup/growth-snapshot', array(
'label' => 'Snapshot do growth',
'description' => 'Resumo do dia: leads, visitas, funil e pipeline.',
'category' => 'logup-growth',
'output_schema' => array( /* JSON Schema */ ),
'execute_callback' => 'logup_ability_growth_snapshot',
'permission_callback' => static fn (): bool => current_user_can( 'manage_options' ),
'meta' => array(
'annotations' => array( 'readonly' => true, 'idempotent' => true ),
'show_in_rest' => true,
),
) );
Na prática: um agente autorizado consegue perguntar “como está o funil hoje?” e receber resposta estruturada, com permissão verificada pelo core — sem eu escrever controller, rota ou documentação. Quando alguém me pergunta se o site da empresa está pronto para a era da IA, é disso que eu estou falando: não é colocar um chatbot na home, é o site expor capacidades de forma que máquinas entendam com segurança.
5. PHP moderno de verdade: enums no lugar de strings soltas
Código WordPress típico ainda é escrito como se fosse PHP 7.4, porque é o mínimo que o core exige. Mas o PHP 8.1 — que é o que roda na minha VPS — já oferece muita coisa que elimina categorias inteiras de bug. A mudança mais bonita foi nos estágios do funil de vendas, que eram strings soltas espalhadas pelo código:
enum LeadStage: string {
case Prospectado = 'prospectado';
case Abordado = 'abordado';
// …
case Entregue = 'entregue';
case Perdido = 'perdido';
public function weight(): float {
return match ( $this ) {
self::Prospectado => 0.05,
self::Abordado => 0.10,
self::Engajado => 0.25,
self::Qualificado => 0.40,
self::Proposta => 0.60,
self::Fechado, self::Entregue => 1.00,
self::Perdido => 0.00,
};
}
}
Um typo de estágio agora explode na hora em vez de virar linha errada no banco. O match é exaustivo: se eu criar um estágio novo e esquecer o peso dele, o PHP acusa — o array antigo aceitava calado. E a regra de caixa (entrada no fechamento, saldo na entrega) virou uma expressão match de cinco linhas em vez de um if/elseif mutável. No pacote foram também str_contains, nullsafe ($post?->ID), arrow functions e mais dois enums (flags de conteúdo e eventos de tracking).
Transparência: rodo PHP 8.1 porque é o pacote do Ubuntu 22.04, com patches da Canonical até 2027. O 8.3 destravaria json_validate() e constantes tipadas; o 8.4, property hooks e array_find(); o 8.5, o pipe operator. Está no mapa — mas a lição é que dá para modernizar muito sem tocar no servidor: enums, match e readonly já estavam disponíveis aqui, parados, esperando alguém usar.
6. As miudezas que somam
- FAQ com
<details name="faq">— o atributonamenativo do HTML faz accordion exclusivo (abrir um fecha o outro) com zero JavaScript. wp_preload_resources— o preload das fontes saiu deprintfmanual no<head>para o filtro oficial do core, que deduplica e ordena.- Limpeza de código morto — o WordPress 7.0 removeu o suporte html5 de
script/style(todo script já sai semtype); o tema parou de declarar o que não existe mais.
O que isso significa se o site é o do seu negócio
Nada acima é enfeite de portfólio. Navegação instantânea segura visitante impaciente em rede móvel. Parser em vez de regex significa que a regra que gera meu lead não quebra com um post formatado diferente. Enum no funil significa que o número que eu olho de manhã está certo. E a Abilities API significa que o site já fala a língua da próxima onda — a dos agentes.
Atualização: o round 2 desta modernização já está no ar — IA nativa no WordPress 7.0: briefing automático de cada lead, usando o AI Client do core e o índice automático que você vê no topo deste artigo.
O padrão que eu vejo com frequência é o contrário: site em WordPress desatualizado, PHP de 2019, tema que ninguém consegue manter, e uma agência trocando de plugin quando algo quebra. Se você quer saber em que ponto o seu está — e o que valeria modernizar primeiro, com custo realista — me deixa seu WhatsApp aqui embaixo que eu olho e te falo o que encontrei, sem compromisso e sem jargão.