log - smart software development. great user experience

Desenvolvimento sobre WordPress (1) — Acções

Este é o primeiro de uma série de artigos de introdução ao desenvolvimento para WordPress que iremos publicar ao longo de 2012, não exigindo mais dos leitores interessados do que um WordPress previamente instalado em servidor próprio e conhecimentos rudimentares de PHP. Pretendemos com isto disseminar know-how sobre a plataforma, bem como partilhar algumas das lições que fomos aprendendo ao longo dos anos.

Localização do functions.php no tema Twenty Eleven

Figura 1: Localização do functions.php no tema Twenty Eleven.

Num artigo futuro abordaremos o desenvolvimento de plugins, mas por agora vamos limitar-nos a criar funcionalidade usando o ficheiro functions.php, mais conveniente para as nossas pequenas experiências. Este ficheiro, que existe na raíz de cada tema WordPress, em /wp-content/themes/(pasta do tema)/functions.php (figura 1), permite a execução de código auxiliar que não faz sentido aplicar transversalmente num plugin.

Importa salientar que o functions.php é específico ao seu tema, e por isso só corre quando o tema está activo, deixando de ter efeito quando se escolhe um diferente.

Vamos, pois, abrir o functions.php no nosso editor de código predilecto (à falta de melhor, um editor de texto básico como o Notepad serve perfeitamente), e prepararmo-nos para dar os primeiros passos por entre as engrenagens do WordPress.

Hooks

A interface de desenvolvimento (ou API) do WordPress assenta maioritariamente no conceito de “hooks”, ou ganchos. Estes hooks dizem respeito a uma série de eventos que podem ocorrer no ciclo de vida da plataforma, e nos quais podemos “pendurar” as nossas próprias funções, alterando o comportamento do WordPress em resposta aos mesmos.

A maior vantagem deste mecanismo de hooks é permitir modificar a plataforma sem mexer no código fonte do próprio WordPress, nem nos temas e plugins de terceiros. As alterações introduzidas através de hooks são modulares e aglomeráveis com as de outros plugins ou temas.

Existem hooks de dois tipos: acções e filtros.

As acções são comportamentos despoletados por uma situação específica, tal como a apresentação do cabeçalho ou rodapé das páginas, a publicação de um artigo, ou a criação de uma nova taxonomia.

Os filtros são semelhantes, com a diferença de terem a capacidade de receber dados, transformá-los, e passá-los à frente. Destes falaremos no próximo artigo.

A minha primeira acção

Para construirmos a nossa primeira acção, precisaremos de criar uma função que a implemente. No final do ficheiro functions.php vamos teclar o seguinte código que escreve uma tag HTML:

function tutorial_meta_greeting () {
    echo '<meta name="greeting" content="Olá, mundo!">';
}

A função tutorial_meta_greeting, só por si, ainda não faz nada. É preciso associá-la a um hook do WordPress que a possa invocar, acrescentando a seguinte linha:

add_action( 'wp_head', 'tutorial_meta_greeting', 10, 0 );

Esta linha diz ao WordPress para executar a nossa função sempre que ocorra um evento com a etiqueta wp_head, um hook que é despoletado aquando da geração do cabeçalho de uma página. Estamos, assim, a escrever uma tag <meta> nos cabeçalhos das nossas páginas. O resultado é visível consultando o HTML de qualquer página do site:

Resultado de tutorial_meta_greeting

Figura 2: O resultado da nossa primeira experiência.

Podemos associar as funções que quisermos ao mesmo hook. Por vezes, no entanto, é preciso garantir que certas funções têm precedência sobre outras. Aqui entra o terceiro parâmetro da função add_action, que diz respeito à prioridade de execução. O parâmetro é opcional, mas no nosso exemplo explicitámos ser 10. Outra função associada a wp_head mas com um nível de prioridade mais baixo correria antes da nossa função. Com um valor mais alto, correria depois. Por exemplo:

function tutorial_meta_before () {
    echo '<meta name="before" content="Antes da saudação.">';
}

function tutorial_meta_after () {
    echo '<meta name="after" content="Depois da saudação.">';
}

add_action( 'wp_head', 'tutorial_meta_before', 5, 0 );
add_action( 'wp_head', 'tutorial_meta_after', 20, 0 );

O quarto parâmetro, que é opcional, indica o número de argumentos que o hook passa à função. No caso do wp_head, não são passados parâmetros.

wp_head é apenas uma de muitas acções. Existe no Codex uma lista de todas as acções suportadas pelo WordPress, sendo também possível criar novas acções e, claro, responder a outras oferecidas por temas e plugins. Também muito útil é o serviço WordPress Hook Database de Adam Brown, que contém uma referência mais técnica de todos os hooks suportados pelo WordPress em cada uma das suas versões.

Mais e melhor

As acções podem servir-se de muitos dados da plataforma, não estando limitadas ao que recebem como argumento. Por exemplo, podemos alterar a nossa função tutorial_meta_greeting para apresentar uma mensagem mais amigável:

function tutorial_meta_greeting ()
{
    global $current_user;
    if (is_user_logged_in()) {
        echo '<meta name="greeting" content="Olá, ' . $current_user->display_name . '!">';
    } else {
        echo '<meta name="greeting" content="Olá, mundo!">';
    }
}

A função acima verifica que o visitante está autenticado usando a função is_user_logged_in do WordPress, e tendo obtido a variável global $current_user, que contém os dados do utilizador, apresenta uma saudação personalizada. Os restantes receberão uma mensagem mais genérica na tag <meta>.

Resultado de tutorial_meta_greeting

Figura 3: Saudação personalizada.

Inserir uma simples tag <meta> no cabeçalho pode não parecer das coisas mais úteis, mas é um exercício simples para explicar a essência do funcionamento dos hooks do WordPress.

Podemos aplicar este conhecimento num exercício mais prático, como adicionar o bloco HTML do Google Analytics ao rodapé das nossas páginas:

function tutorial_add_google_analytics () {
    $tracking_code = 'UA-XXXXX-X'; // Não se esqueça de me definir
    echo '<script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>';
    echo '<script type="text/javascript">';
    echo 'var pageTracker = _gat._getTracker("' . $tracking_code . '");';
    echo 'pageTracker._trackPageview();';
    echo '</script>';
}
add_action( 'wp_footer', 'tutorial_add_google_analytics' );

Outras utilizações práticas das acções contemplam, por exemplo:

  • Envio de emails sempre que um novo artigo é publicado;
  • Registo das autenticações feitas pelos utilizadores num ficheiro de log ou em base de dados;
  • Inicializar ou preparar dados no início de um pedido de página.

Remover acções

Tal como associamos funções a hooks, também temos a possíbilidade de as retirar com a função remove_action. Suponhamos que apenas nos interessam estatísticas de utilização de visitantes autenticados, e que por isso devemos ignorar a função tutorial_add_google_analytics para os restantes.

if (!is_user_logged_in())
    remove_action( 'wp_footer', 'tutorial_add_google_analytics' );

Mais uma vez, usámos is_user_logged_in para determinar se o visitante está autenticado, e se não estiver retiramos a função tutorial_add_google_analytics do rol de acções a executar no hook wp_footer. À semelhança do add_action, podemos indicar a prioridade e o número de argumentos se quisermos apenas retirar ocorrências específicas de uma função.

Uma aplicação simples e muito prática de remove_action consiste em eliminar algumas das tags HTML que denunciam versões antigas e potencialmente inseguras a visitantes mal-intencionados. Como esta:

<meta name="generator" content="WordPress 3.3">

Para ocultar estes dados, inseridos no cabeçalho pela função interna do WordPress wp_generator, é preciso acrescentar o seguinte ao functions.php:

remove_action( 'wp_head', 'wp_generator' );

Novas acções

Definir novas acções personalizadas é tão simples quando invocá-las em qualquer parte do nosso código usando do_action. Acrescentando ao final do functions.php o seguinte:

do_action( 'tutorial_new_action' );                             // Sem argumentos
do_action( 'tutorial_new_action', $arg1 );                      // Com 1 argumento
do_action( 'tutorial_new_action', $arg1, $arg2 );               // Com 2 argumentos
do_action( 'tutorial_new_action', $arg1, $arg2, ..., $argN );   // Com N argumentos

Esta linha irá activar todas as funções que estejam associadas ao hook tutorial_new_action, podendo passar-lhes zero ou mais argumentos.

No próximo artigo, irei debruçar-me sobre a segunda classe de hooks, os filtros, onde aprenderemos a criar funções para transformar a apresentação de conteúdos do WordPress.

Até lá teremos muito gosto em receber feedback e ouvir as questões dos leitores na nossa página no Facebook.