Desenvolvimento sobre WordPress — Filtros (tutorial)
Na primeira parte desta série de artigos de introdução ao desenvolvimento sobre WordPress, aprendemos a personalizar um tema através dos hooks de acção. Este hooks permitem associar código nosso a acontecimentos de interesse no sistema, como o pedido de uma página ou a publicação de um artigo ou comentário. Tudo sem interferir com o núcleo do WordPress, que se quer livre de código personalizado para facilitar as actualizações.
Filtros
Vimos também no primeiro artigo que existe uma segunda classe de hooks, chamados filtros, sobre os quais nos iremos agora debruçar. Estes são em tudo semelhantes às acções, com uma diferença de nota: todas as funções de filtro recebem pelo menos um parâmetro e retornam, transformado ou não, o primeiro desses parâmetros recebidos.
Por esse motivo, e como o próprio nome indica, são perfeitos para transformação e processamento de informação, ou para aplicar em validações da mesma, antes de a escrever na base de dados ou a mostrar ao visitante do site. Neste texto iremos experimentar alguns exemplos.
O meu primeiro filtro
Como antes, concentraremos as nossas modificações no ficheiro functions.php do tema, situado em /wp-content/themes/pasta do tema/functions.php, e só mais tarde aplicaremos o conhecimento adquirido ao desenvolvimento de uma nova extensão.
O procedimento para criação e registo de um filtro é semelhante ao das acções, sendo necessário escrever a função de filtragem em PHP e associá-la a um filtro do WordPress usando add_filter().
Para o nosso primeiro exemplo, iremos personalizar a apresentação das nossas listagens, transformando o texto da hiperligação “Continuar a ler” dos artigos separados por um More… com algo um pouco mais elaborado.

Figura 1: O que pretendemos modificar.
function tutorial_the_content_more_link ( $output, $more_link_text ) {
$more_link_url = get_permalink() . '#more-' . get_the_ID();
$new_more_link_text = "Continue a ler, modificado pelo meu primeiro filtro →";
$output = ' ' . $new_more_link_text . '';
return $output;
}
Tal como com as acções, é imperativo registar o filtro. Vamos usar a função add_filter() para associar a nossa função ao filtro excerpt_more:
add_filter( 'the_content_more_link', 'tutorial_the_content_more_link', 10, 2 );
Por partes, então.
Primeiro que tudo, o filtro a que a vamos associar (the_content_more_link), recebe dois parâmetros: sendo o primeiro a hiperligação já construída, e o segundo o texto simples dessa hiperligação. O 2 na linha do add_filter() indica isso mesmo, à semelhança do que já acontecia com as acções. O 10 indica a prioridade do filtro, mais uma vez em tudo semelhante ao que vimos antes. Quanto maior, mais tarde na sequência de filtros do the_content_more_link há-de correr.
Neste caso, interessa-nos reconstruir por completo a hiperligação, não preservando o que vem de trás. Para tal, precisamos de construir o endereço de destino à custa das funções get_permalink() e get_the_ID(), guardando-o na variável $more_link_url.
No final, redefinimos a variável $output com o HTML da hiperligação que pretendemos apresentar e retornamos esse valor. Se não for modificado por mais nenhum filtro, este será o HTML a apresentar ao visitante do site.

Figura 2: A hiperligação modificada.
É claro que a nossa função tutorial_the_content_more_link() pode conter código mais sofisticado para, por exemplo, apresentar o total de palavras no artigo.
function tutorial_the_content_more_link_wordcount( $output, $more_link_text ) {
global $post;
$word_count = str_word_count( strip_tags( $post->post_content ) );
$more_link_text = "Continue a ler ($word_count palavras) →";
$more_link_url = get_permalink() . '#more-' . get_the_ID();
$output = ' ' . $more_link_text . '';
return $output;
}
add_filter( 'the_content_more_link', 'tutorial_the_content_more_link_wordcount', 20, 2 );
Aqui, vamos precisar de obter dados do artigo em questão que não são passados por parâmetro à nossa função. Para isso declaramos a variável global $post na nossa função, de forma a podermos aceder ao valor de $post->get_content, que contém todo o texto do artigo.
Com o texto completo do artigo na nossa posse, podemos finalmente contabilizar o total de palavras com str_word_count, tendo o cuidado primeiro de limpar o HTML existente no artigo usando strip_tags. O resto é semelhante à primeira função que vimos, com a diferença de agora imprimirmos o total de palavras.

Figura 3: A hiperligação com contador de palavras.
Encadeamento de filtros
Em certos casos poderá ser necessário associar várias funções ao mesmo filtro. Não há qualquer problema: tal como as acções, os filtros são executados em sequência, segundo a prioridade definida (como nas acções, mais uma vez) e a ordem em que foram registados.
Para exemplificar este mecanismo, vamos alterar a apresentação do título do artigo com o filtro the_title para, mais uma vez, mostrar o contador de palavras, e também acrescentar uma tag HTML em torno do texto.
function tutorial_the_title_em ( $title, $id ) {
return "$title";
}
function tutorial_the_title_wordcount ( $title, $id ) {
if ($id) {
$post = &get_post( $id );
$word_count = str_word_count( strip_tags( $post->post_content ) );
return $title . " ($word_count palavras)";
} else {
return $title;
}
}
add_filter( 'the_title', 'tutorial_the_title_em', 10, 2 ); // Prioridade 10
add_filter( 'the_title', 'tutorial_the_title_wordcount', 20, 2 ); // Prioridade 20
Dado que o filtro the_title aceita entre os seus parâmetros o identificador do artigo, e não havendo garantias de que a função vai correr dentro do loop de apresentação de posts do WordPress, teremos de obter o conteúdo do artigo sem recorrer à variável global $post. Usamos por isso a função get_post() do WordPress para conseguir o mesmo efeito.

Figura 4: Título com itálico aplicado primeiro e total de palavras acrescentado depois.
Na sequência de filtros acima, o título é colocado em itálico primeiro e depois é-lhe acrescentado o total de palavras. Contudo, se invertermos a prioridade…
add_filter( 'the_title', 'tutorial_the_title_em', 20, 2 ); // Prioridade 20 add_filter( 'the_title', 'tutorial_the_title_wordcount', 10, 2 ); // Prioridade 10
…então é aplicado o contador primeiro e depois é tudo posto a itálico.

Figura 5: Título com total de palavras acrescentado primeiro e itálico aplicado depois.
the_title e the_content_more_link são apenas dois de uma imensa variedade de filtros. Existe no Codex uma lista de todos os filtros suportados pelo WordPress, sendo também possível criar novos filtros e, claro, usar os filtros criados por outros temas e plugins. Nunca é demais recomendar a WordPress Hook Database de Adam Brown, contendo informação mais pormenorizada sobre todos os hooks suportados pelo WordPress em cada uma das suas versões.
Eliminar filtros
Da mesma forma que associamos funções a filtros, também podemos eliminar essa associação. Vimos no primeiro artigo que esse processo era levado a cabo pela função remove_action().
Aqui, passa-se exactamente o mesmo, a única diferença é a função chamar-se remove_filter(). Por exemplo, a seguinte invocação impediria a execução da função tutorial_the_title_wordcount() previamente associada ao filtro the_title.
// Retira o filtro com prioridade 10 apenas: remove_filter( 'the_title', 'tutorial_the_title_wordcount', 10 ); // Retira o filtro com prioridade 20 apenas: remove_filter( 'the_title', 'tutorial_the_title_wordcount', 20 );
Já a função remove_all_filters() impede a execução de todas as funções associadas a um dado filtro. Por exemplo, todos os fitros the_title declarados antes desta linha deixarão de ser executados:
remove_all_filters( 'the_title' ); // Mas este, associado depois da limpeza, já corre: add_filter( 'the_title', 'tutorial_the_title_em', 10, 2 );
Novos filtros
À semelhança do do_action() apresentado na sessão anterior, que invoca uma acção (nova ou existente), existe uma função análoga para os filtros chamada apply_filters().
Podemos, por exemplo, aplicar os filtros de título do WordPress (incluindo os acima declarados) a uma cadeia arbitrária de caracteres fazendo:
// Associar a função a um novo filtro: add_filter( 'custom_the_title', 'tutorial_the_title_em', 10, 2 ); // Invocar o novo filtro... $filtered_title = apply_filters( 'custom_the_title', 'Hello, world!', 0 ) echo $filtered_title; // ...ou mesmo um filtro que já exista. $filtered_title = apply_filters( 'the_title', 'Hello, world!', 0 ) echo $filtered_title;
No próximo artigo, abordaremos a API de shortcodes do WordPress, um mecanismo com tags especiais que podem ser incluídas no conteúdo dos artigos com funcionalidade de apresentação difícil ou mesmo impossível de reproduzir através do editor visual.