Desativar a pesquisa no WordPress sem plugin (functions.php, ?s=)

O código completo para desativar a pesquisa do WordPress sem plugin: devolver um 404 nos URL ?s=, retirar o formulário, o widget e o bloco de pesquisa, fechar o ponto de acesso REST, e a variante .htaccess.

Desativar a pesquisa no WordPress: com código ou com um plugin
Resposta rápida

Acrescenta ao ficheiro functions.php do teu tema um filtro em parse_query que transforma qualquer pesquisa num 404, um filtro get_search_form que devolve uma string vazia, e retira o widget e o bloco de pesquisa. O código completo, testado no WordPress 7.1, está no artigo; não é preciso nenhum plugin.

Um site montra de cinco páginas, um site one-page, um portefólio: a pesquisa do WordPress não serve de nada e o seu formulário atravanca o tema. Pior, a página de resultados existe mesmo sem formulário, no endereço /?s=mot, e mostra uma página vazia ou uma lista de conteúdos que nunca quiseste destacar. Eis como desativar completamente a pesquisa no WordPress, sem plugin, com um excerto para functions.php.

Porquê desativar a pesquisa

  • Não serve de nada num site pequeno: tudo está acessível a partir do menu, num clique.
  • Produz páginas de resultados sem valor, que os robôs podem pedir com qualquer palavra, o que desperdiça recursos do servidor e cria URL parasitas.
  • O formulário imposto pelo tema muitas vezes não tem lugar no design.

O código completo para functions.php

A colocar no ficheiro functions.php do teu tema-filho (ou num pequeno plugin próprio, para sobreviver às mudanças de tema). Cada bloco fecha uma porta diferente.

functions.php
<?php
/**
 * Desativa a pesquisa do WordPress do lado público.
 */

// 1. Qualquer pesquisa por URL (/?s=mot ou /search/mot/) passa a ser uma página 404.
add_action( 'parse_query', function ( WP_Query $query ) {
    if ( is_admin() || ! $query->is_main_query() || ! $query->is_search() ) {
        return;
    }
    $query->is_search = false;
    $query->set_404();
    status_header( 404 );
    nocache_headers();
} );

// 2. O formulário de pesquisa do tema deixa de ser apresentado.
add_filter( 'get_search_form', '__return_empty_string' );

// 3. O widget de pesquisa clássico é retirado.
add_action( 'widgets_init', function () {
    unregister_widget( 'WP_Widget_Search' );
}, 11 );

// 4. O bloco «Pesquisa» do editor desaparece do menu de inserção.
add_filter( 'allowed_block_types_all', function ( $allowed ) {
    if ( ! is_array( $allowed ) ) {
        $registry = WP_Block_Type_Registry::get_instance();
        $allowed  = array_keys( $registry->get_all_registered() );
    }
    return array_values( array_diff( $allowed, [ 'core/search' ] ) );
} );

// 5. O ponto de acesso REST de pesquisa é fechado.
add_filter( 'rest_endpoints', function ( array $endpoints ) {
    unset( $endpoints['/wp/v2/search'], $endpoints['/wp/v2/search/(?P<id>[\d]+)'] );
    return $endpoints;
} );

O que faz cada bloco:

  1. A consulta. Em parse_query, se a consulta principal for uma pesquisa do lado público, é transformada num 404 com set_404() e o código HTTP correspondente. is_admin() mantém intacta a pesquisa da administração; is_main_query() evita mexer nas consultas secundárias das extensões.
  2. O formulário. get_search_form() é a função que os temas chamam para mostrar o formulário; o filtro faz com que devolva uma string vazia.
  3. O widget dos temas clássicos.
  4. O bloco dos temas baseados em blocos. O filtro recebe ou true (todos os blocos autorizados), ou uma lista: no primeiro caso, reconstrói-se a lista completa antes de lhe retirar core/search.
  5. A API REST. /wp-json/wp/v2/search?search=mot passa a devolver um erro rest_no_route em vez de uma lista de resultados.

Verificar

Bastam três pedidos, num navegador ou com curl:

bash
curl -s -o /dev/null -w "%{http_code}\n" "https://exemple.fr/?s=test"
# 404

curl -s "https://exemple.fr/wp-json/wp/v2/search?search=test" | head -c 120
# {"code":"rest_no_route","message":"Não foi encontrada nenhuma rota que corresponda ao URL e ao método do pedido."…

curl -s "https://exemple.fr/" | grep -c 'role="search"'
# 0: já não há formulário na página (se o tema passar por get_search_form)

Na administração, a pesquisa de artigos, de páginas e de multimédia tem de continuar a funcionar.

Se o tema mostrar o seu próprio formulário

Alguns temas escrevem o formulário diretamente nos seus modelos (header.php, searchform.php) sem passar por get_search_form(). Nesse caso, o filtro não tem qualquer efeito na apresentação. Duas opções: sobrepor o modelo em causa num tema-filho, ou esconder o formulário em CSS entretanto:

css
.search-form,
form[role="search"] {
  display: none;
}

O CSS apenas esconde: o bloqueio de /?s= pelo primeiro bloco PHP continua indispensável.

Variante: redirecionar ?s= no .htaccess

Se preferires não servir um 404 mas antes reencaminhar para a página inicial, uma regra Apache faz isso antes mesmo de o WordPress ser executado. Está limitada à raiz do site para não mexer na pesquisa da administração (wp-admin/edit.php?s=…).

.htaccess
# A colocar antes do bloco # BEGIN WordPress
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)s= [NC]
RewriteRule ^$ /? [R=301,L]

O ? final esvazia a query string do redirecionamento. Esta regra e o código PHP não se excluem: a primeira poupa ao servidor a execução do WordPress, o segundo continua a ser a proteção de referência, incluindo para as ligações permanentes /search/mot/.

Existe e faz o mesmo. Na Gekkode, a linha editorial é não acrescentar uma extensão para aquilo que um tema faz em trinta linhas: menos uma dependência para atualizar e um comportamento que lês no teu próprio código. Se administras vários sites sem tema-filho, o plugin continua a ser uma opção razoável.

Na mesma linha, limitar o acesso ao back-office do WordPress e migrar um site WordPress são outras duas operações que se fazem sem extensão.

Erros frequentes

Bloquear também a pesquisa da administração Um teste is_search() sem is_admin() parte a pesquisa nas listas de artigos e de multimédia do painel. O código do artigo exclui a administração.
Retirar o formulário e esquecer o URL O formulário é apenas uma porta: /?s=mot continua acessível a quem escrever o URL. É o filtro em parse_query que fecha a porta, não a remoção do formulário.
Uma redireção .htaccess em todo o site Uma regra sobre s= sem restrição de caminho redireciona também wp-admin/edit.php?s=…. Limita a regra à raiz do site.
Um tema que mostra o seu próprio formulário Se o tema não usar get_search_form(), o filtro não o retira. É preciso então alterar o modelo do tema (de preferência o filho).

WordPress

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.