Desenvolvimento sobre WordPress (3) — Shortcodes
Nas primeiras duas partes da nossa série de artigos introdutórios sobre desenvolvimento em WordPress, centrámo-nos na API de hooks, que serve para invocar funções que executem acções ou filtrem dados em resposta a acontecimentos na plataforma.
Trataremos agora da API de shortcodes do WordPress, que permite que usemos, no conteúdo de artigos e páginas, um conjunto de códigos macro delimitados por parênteses rectos ([]) e inspirados pela linguagem de formatação BBCode. No momento da apresentação ao visitante do site, estes macros são substituídos pelo resultado da função que abstraem.
O WordPress inclui de origem alguns destes shortcodes. Por exemplo, o shortcode [gallery] é substituído por uma galeria de fotografias com todas as imagens que estiverem anexadas ao artigo ou página onde se encontra. Um shortcode é descrito de forma muito semelhante a uma vulgar tag HTML, permitindo atributos e tags de abertura e fecho. Por exemplo, [gallery id="3"] ou [block]Lorem ipsum[/block].
Para além dos shortcodes oferecidos pelo WordPress, tanto temas como plugins podem criar novos códigos. É o que iremos descobrir neste artigo.
O meu primeiro shortcode
Como nos artigos anteriores, 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.
Para criar um novo shortcode em código basta, muito simplesmente, declarar uma função que o implemente e associá-la ao nome pretendido com add_shortcode(). A forma de o fazer é semelhante ao que já fazíamos para os hooks:
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
return 'Olá, mundo!';
}
add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
E pronto! Experimente inserir o shortcode [hello] no conteúdo de qualquer página ou artigo, e este será substituído pela expressão “Olá, mundo!” aquando da visualização.
Atributos do shortcode
Como já demos a entender, é possível passar atributos a um shortcode, à semelhança do que acontece em BBCode ou em HTML. Os mais atentos terão reparado que a função tutorial_hello_world_shortcode() aceita um parâmetro $atts, que recebe precisamente um array de parâmetros passados no shortcode.
Não é preciso fazer nada de especial para obter estes parâmetros, já que a API do WordPress abstrai o processo de análise da string para recolha dos parâmetros. Um shortcode com o seguinte formato:
[hello name="Luís Rodrigues" other="Outro atributo"]
irá invocar a nossa função tutorial_hello_world_shortcode() com o seguinte array passado por parâmetro:
Array
(
[name] => Luís Rodrigues
[other] => Outro atributo
)
Isto significa que podemos modificar a nossa função para lhe dar um toque mais pessoal:
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
if (empty( $atts['name'] ))
return 'Olá, mundo!';
else
return 'Olá, ' . $atts['name'] . '!';
}
add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
Assim, podemos escrever o shortcode
[hello name="Luís Rodrigues"]
e obter
Olá, Luís Rodrigues!
Conteúdo do shortcode
O shortcode acima limita-se a substituir todo o código pelo retorno da função associada. Contudo, também é possível usar shortcodes para filtrar blocos de conteúdo sem o substituir por completo.
Aqui entra em palco o segundo parâmetro da nossa função, $content, que guarda todo o conteúdo existente entre a abertura e fecho de um shortcode.
function tutorial_hello_world_shortcode ( $atts, $content = null ) {
$name = empty( $atts['name'] ) ? 'mundo' : $atts['name'];
$output = "<strong>Olá, $name!</strong> ";
if (!is_null( $content )) {
$output .= $content;
$output .= " <strong>Adeus, $name!</strong>";
}
return $output;
}
add_shortcode( 'hello', 'tutorial_hello_world_shortcode' );
A inserção do shortcode revisto no nosso artigo ou página poderia ter o formato
[hello name="Luís Rodrigues"]Lorem ipsum dolor sit amet...[/hello]
resultando em
Olá, Luís Rodrigues! Lorem ipsum dolor sit amet… Adeus, Luís Rodrigues!
A invocação anterior, contendo apenas um código [hello] simples, com o sem atributo, continuaria a funcionar da mesma forma, já que o código da nossa função verifica a existência ou não-existência do atributo name e do conteúdo.
Valores por omissão
No código do nosso exemplo anterior, ocorre uma verificação prévia do atributo name e a atribuição do valor por omissão "mundo" caso este não se encontre definido.
Há, no entanto, uma forma mais elegante e recomendada de indicar os valores por omissão e extrair os valores de um conjunto de atributos. Assim, em vez de
$name = empty( $atts['name'] ) ? 'mundo' : $atts['name'];
podemos escrever
extract( shortcode_atts( array(
'name' => 'mundo',
'other' => 'XPTO' // Valor por omissão para outro atributo
), $atts ) );
Exemplo útil
Os shortcodes têm inúmeras aplicações práticas, uma das quais sendo a possibilidade de limitar a visualização de conteúdos tendo em conta um conjunto de condições.
Por exemplo, podemos criar um novo shortcode [access] que limite o acesso de utilizadores não-autenticados aos conteúdos delimitados pelo shortcode.
function shortcode_access_control ( $atts, $content = null ) {
extract( shortcode_atts( array(
'capability' => 'read',
'error' => 'Este conteúdo está reservado a utilizadores autenticados.',
), $atts ) );
if (current_user_can( $capability ) && !is_null( $content ))
return $content;
else
return $error;
}
add_shortcode( 'access', 'shortcode_access_control' );
O shortcode pode ser invocado digitando o seguinte texto algures no conteúdo de uma página ou artigo:
[access]TOP SECRET![/access]
Um utilizador autenticado verá o seguinte:
TOP SECRET!
Todos os restantes verão antes a mensagem:
Este conteúdo está reservado a utilizadores autenticados.
Por omissão, esta função verifica se o utilizador tem a autorização read (ou a capacidade que for indicada no parâmetro capability). Se a autorização tiver sido concedida, é apresentado o conteúdo, caso contrário mostramos a mensagem de erro (ou a que for indicada no atributo message).
Dado que este novo shortcode permite parametrizar a capacidade requerida do utilizador e a mensagem de erro, temos alguma flexibilidade nas opções de validação e apresentação. Por exemplo:
[access capability="admin" error="Este conteúdo só pode ser visto por administradores."]TOP SECRET![/access]
Precauções
Apesar de poderosa, a API de shortcodes apresenta algumas limitações a ter em consideração.
Uma destas particularidades tem a ver com o facto de a função que interpreta os shortcodes varrer o conteúdo dos artigos e das páginas uma única vez. Isto significa que incluir shortcodes dentro uns dos outros pode não surtir os efeitos desejados. Por exemplo:
[access]
O meu primeiro shortcode: [hello]
[/access]
Não funciona, apresentando aos utilizadores autenticados apenas o texto “O meu primeiro shortcode: [hello]”, sem substituir o fragmento “[hello]” como seria de esperar.
Uma forma de contornar esta limitação é passar o $content do shortcode pela função do_shortcode() antes de o devolver. Feita a alteração, a função terá o seguinte aspecto:
function shortcode_access_control ( $atts, $content = null ) {
extract( shortcode_atts( array(
'capability' => 'read',
'error' => 'Este conteúdo está reservado a utilizadores autenticados.',
), $atts ) );
if (current_user_can( $capability ) && !is_null( $content ))
return do_shortcode( $content ); // Processamento de sub-shortcodes
else
return $error;
}
add_shortcode( 'access', 'shortcode_access_control' );
Aqui, a função do_shortcode() obriga o WordPress a interpretar recursivamente o conteúdo em busca de novos shortcodes para substituir.
Mais problemático é o facto do interpretador do WordPress não reconhecer duas ou mais ocorrências do mesmo shortcode encadeadas. Por exemplo:
[shortcode]
[shortcode][/shortcode]
[/shortcode]
Não irá funcionar, mesmo usando a função do_shortcode(), dado que a função que interpreta os shortcodes privilegia a velocidade de processamento e não a correcta interpretação de estruturas complexas destes códigos.
Deve-se evitar usar hífens no nome do shortcode, pois estes não são correctamente reconhecidos pelo interpretador devido a um bug nas actuais versões do WordPress. Prefere-se aqui o uso do carácter _ (underscore). Também não são aceites parênteses rectos no valor de um atributo: algo como [shortcode atributo="[valor]"] irá falhar.
No próximo artigo, iremos explicar o processo de desenvolvimento de novas widgets para apresentação nos temas. Até lá, aguardamos questões e sugestões dos nossos leitores na nossa página no Facebook.