Skip to content
⚡ Como adicionar o seu próprio shortcode no WordPress: exemplos e código

⚡ Como adicionar o seu próprio shortcode no WordPress: exemplos e código

Precisa de apresentar a data da última atualização de um artigo no rodapé de cada publicação. Ou inserir um formulário de subscrição exatamente a meio do texto, sem malabarismos de editor de código e templates. No WordPress, os shortcodes são a ferramenta para isso.

Um shortcode é uma etiqueta curta entre parênteses retos: [myshortcode]. O WordPress encontra-a no conteúdo e substitui-a pelo resultado de uma função PHP. Usa shortcodes padrão como [gallery] e [embed] a toda a hora, sem sequer pensar nisso. Mas o seu próprio shortcode é uma alavanca: escreve a lógica uma vez e o editor insere-a em qualquer lado com três cliques.

Em 10 minutos vai criar o seu primeiro shortcode funcional: de uma função vazia a uma etiqueta com atributos e conteúdo encapsulado. O código é real, funciona em qualquer WordPress moderno e foi testado num site de staging.

💡 Visão geral rápida:

  • A função add_shortcode: o que aceita e como funciona internamente
  • Um shortcode básico [current_year], o ano atual em texto
  • Um shortcode com atributos [cta text="Скачать"], um botão personalizado
  • Um shortcode com conteúdo encapsulado [notice]Текст[/notice], um bloco com estilo
  • Adicionar via um plugin ou functions.php: prós e contras de cada abordagem
  • Erros comuns: echo em vez de return, conflitos de nomes, atributo vazio no PHP 8+

O que o add_shortcode pode fazer e como funciona

A função add_shortcode é a única forma padrão de registar um novo shortcode no WordPress. Aceita dois parâmetros:

  • $tag (string), o nome do shortcode que vai escrever entre parênteses retos. Apenas letras, números e underscores. Espaços e caracteres especiais & / < > [ ] = são proibidos; o WordPress recusará silenciosamente registar essa etiqueta.
  • $callback (callable), o nome da função PHP que será executada quando o shortcode for encontrado. Esta função gera o HTML que o visitante verá.

O código fonte da função, cinco linhas de lógica e duas verificações de integridade (listagem completa em developer.wordpress.org):

1function add_shortcode( $tag, $callback ) {
2 global $shortcode_tags;
3
4 if ( '' === trim( $tag ) ) {
5 _doing_it_wrong(
6 __FUNCTION__,
7 __( 'Invalid shortcode name: Empty name given.' ),
8 '4.4.0'
9 );
10 return;
11 }
12
13 if ( 0 !== preg_match( '@[<>&/\[\]\x00-\x20=]@', $tag ) ) {
14 _doing_it_wrong(
15 __FUNCTION__,
16 sprintf(
17 /* translators: 1: Shortcode name, 2: Space-separated list of reserved characters. */
18 __( 'Invalid shortcode name: %1$s. Do not use spaces or reserved characters: %2$s' ),
19 $tag,
20 '& / < > [ ] ='
21 ),
22 '4.4.0'
23 );
24 return;
25 }
26
27 $shortcode_tags[ $tag ] = $callback;
28}

O ponto-chave: $shortcode_tags, um array global. O WordPress armazena nele todos os shortcodes registados. Durante a renderização do conteúdo, o núcleo itera sobre este array e chama a função associada para cada etiqueta encontrada. Daí decorrem duas implicações:

  • *Registar no hook init.* Se chamar add_shortcode diretamente num ficheiro de plugin, pode ser executado antes de o WordPress estar totalmente inicializado. A forma correta é envolvê-lo num hook:
1add_action( 'init', 'my_register_shortcodes' );
2
3function my_register_shortcodes() {
4 add_shortcode( 'mytag', 'my_shortcode_callback' );
5}
  • Um prefixo é obrigatório. O array global é partilhado por todos os plugins e pelo tema. Se der a um shortcode o nome [button], o seu [button] substitui silenciosamente o mesmo shortcode de um plugin de formulários. Um prefixo como myplugin_ ou uma abreviatura única resolve o problema. Nos exemplos abaixo uso o prefixo mysite_; num projeto real, substitua-o pelo seu.

Passo 1: um shortcode simples sem parâmetros

O caminho mais curto para um shortcode funcional, três linhas no functions.php do seu tema filho (ou no plugin Code Snippets, que é mais seguro e não se perde numa atualização do tema).

Adicione este código e guarde:

1add_shortcode( 'mysite_current_year', 'mysite_display_current_year' );
2
3function mysite_display_current_year() {
4 return date( 'Y' );
5}

Agora escreva [mysite_current_year] em qualquer artigo ou página. No front-end, o ano atual aparecerá em vez do shortcode: "2026".

O que acontece aqui. A função mysite_display_current_year não recebe argumentos, chama a função PHP date('Y') e devolve uma string de quatro dígitos. O WordPress insere esta string exatamente onde o shortcode foi colocado. Não há magia.

Onde aplicar isto na prática: o ano no rodapé (© [mysite_current_year]), a idade do projeto em texto («a trabalhar desde [mysite_current_year]»), a atualização automática de datas em páginas de conformidade legal.

Passo 2: um shortcode com atributos

Um shortcode sem parâmetros é útil, mas a verdadeira flexibilidade começa com os atributos. O exemplo clássico, um botão com texto e link personalizáveis:

1add_shortcode( 'mysite_cta', 'mysite_cta_button' );
2
3function mysite_cta_button( $atts ) {
4 $atts = shortcode_atts(
5 array(
6 'text' => 'Learn more',
7 'url' => '#',
8 ),
9 $atts,
10 'mysite_cta'
11 );
12
13 return sprintf(
14 '<a href="%s" class="mysite-cta-button">%s</a>',
15 esc_url( $atts['url'] ),
16 esc_html( $atts['text'] )
17 );
18}

No editor, utilize-o assim:

1[mysite_cta text="Download plugin" url="https://example.com/myplugin/"]

A função shortcode_atts faz três coisas ao mesmo tempo: combina os atributos do utilizador com os valores predefinidos, filtra apenas as chaves conhecidas e normaliza uma string vazia num array (sem isto, chamar [mysite_cta] sem atributos no PHP 8+ lançaria um TypeError, porque o primeiro parâmetro da função de callback receberia uma string vazia em vez de um array).

*Porquê esc_url e esc_html.* Um shortcode é inserido por um editor, hoje é você, e amanhã um gestor de conteúdos sem acesso ao código. O escape de saída protege contra XSS acidental se um parêntesis angular ou tag aparecer no atributo text.

Passo 3: um shortcode com conteúdo delimitado

Alguns shortcodes envolvem um fragmento de texto: [mysite_notice]Важное сообщение[/mysite_notice]. O conteúdo delimitado chega ao callback como o segundo parâmetro, $content. Um cenário típico, um bloco de aviso estilizado:

1add_shortcode( 'mysite_notice', 'mysite_notice_box' );
2
3function mysite_notice_box( $atts, $content = null ) {
4 $atts = shortcode_atts(
5 array(
6 'type' => 'info',
7 ),
8 $atts,
9 'mysite_notice'
10 );
11
12 $class = 'notice-' . esc_attr( $atts['type'] );
13
14 return sprintf(
15 '<div class="mysite-notice %s"><p>%s</p></div>',
16 $class,
17 do_shortcode( $content )
18 );
19}

Note o do_shortcode( $content ). Se o editor inseriu outro shortcode dentro do seu shortcode (por exemplo [mysite_current_year]), este invólucro também o executará. Sem do_shortcode, os shortcodes aninhados serão exibidos como texto entre parêntesis retos, [mysite_current_year] em bruto em vez de «2026».

CSS para o bloco, mínimo, para começar:

1.mysite-notice {
2 border-left: 4px solid #2271b1;
3 background: #f0f6fc;
4 padding: 1em 1.2em;
5 margin: 1.5em 0;
6 border-radius: 4px;
7}
8.mysite-notice.notice-warning {
9 border-left-color: #dba617;
10 background: #fcf9e8;
11}

Adicione os estilos ao style.css do seu tema filho ou através de Aparência → Personalizar → CSS adicional.

Passo 4: um shortcode dentro de um plugin (abordagem OOP)

Quando tem mais de três shortcodes, o functions.php transforma-se num depósito. É altura de mover a lógica para um plugin separado e, idealmente, para uma classe. Aqui está um esqueleto de mini-plugin com um shortcode:

1<?php
2/**
3 * Plugin Name: MySite Shortcodes
4 * Description: Custom shortcodes for the site.
5 * Version: 1.0.0
6 * Requires PHP: 7.4
7 */
8
9defined( 'ABSPATH' ) || exit;
10
11class MySite_Shortcodes {
12
13 public static function init() {
14 add_action( 'init', array( __CLASS__, 'register' ) );
15 }
16
17 public static function register() {
18 add_shortcode( 'mysite_email', array( __CLASS__, 'email_obfuscated' ) );
19 }
20
21 public static function email_obfuscated( $atts ) {
22 $atts = shortcode_atts(
23 array( 'address' => '' ),
24 $atts,
25 'mysite_email'
26 );
27
28 if ( ! is_email( $atts['address'] ) ) {
29 return '';
30 }
31
32 return sprintf(
33 '<a href="mailto:%1$s">%1$s</a>',
34 antispambot( $atts['address'], 1 )
35 );
36 }
37}
38
39MySite_Shortcodes::init();

Coloque este ficheiro em wp-content/plugins/mysite-shortcodes/mysite-shortcodes.php e ative o plugin no painel de administração. O shortcode [mysite_email address="hello@example.com"] produzirá um link protegido contra bots de spam; a função antispambot codifica os caracteres do email em entidades HTML.

Porquê uma classe e não um conjunto de funções. Namespacing: três shortcodes numa classe não colidirão com funções de terceiros. Mais autoloading, mais código legível se o plugin crescer para uma dúzia de shortcodes.

Testar um shortcode antes de publicar

Depois de adicionar o código, verifique três cenários:

  • Shortcode sem atributos. Apenas [mysite_cta], deve ser renderizado com os valores predefinidos (texto «Saiba mais», link #).
  • Shortcode com atributos. Um conjunto completo de parâmetros, todos os valores são captados e exibidos corretamente.
  • Erro nos atributos. Um email inválido em [mysite_email], a função devolve silenciosamente uma string vazia em vez de quebrar a página.

Importante: nunca use echo dentro de uma função de callback. Um shortcode deve devolver uma string via return. Se produzir HTML com echo, este aparecerá não onde o shortcode está, mas no topo da página, porque o WordPress executa a renderização do shortcode antes da saída do conteúdo. A mesma lógica dos filtros: a função devolve um valor, e o próprio motor decide onde o inserir.

Uma segunda nuance: se o shortcode não for exibido (vê [mysite_cta] como texto, não um botão), verifique se a função está registada no hook init, e não diretamente no corpo do plugin. Sem init, o array global $shortcode_tags pode ainda não estar pronto para aceitar novas tags.

Shortcode num tema vs. um plugin: o que escolher

Critério

Tema functions.php

Plugin separado

Velocidade de arranque

Mais rápido - ficheiro já está carregado

Ligeiramente mais lento - ficheiro separado

Portabilidade

Vinculado ao tema

Funciona com qualquer tema

Sobrevivência a atualizações

Perdido na atualização do tema

Vive de forma independente

Conveniência de edição

Aparência → Editor de Ficheiros do Tema

Editor de plugins ou FTP

Para quantos shortcodes

1-3

4+

A regra: comece com functions.php num site de teste, construa três shortcodes e depois mova-os para um plugin. Uma atualização do tema seis meses depois não enterrará a sua lógica, e pode transferir os shortcodes para outro projeto num minuto.

⁉️🤔 Perguntas frequentes

Qual é a diferença entre um shortcode e um bloco Gutenberg?

Um shortcode é uma etiqueta de texto entre parênteses retos que é processada no lado do servidor. Um bloco é um componente visual do editor, um componente React com definições na barra lateral. Os shortcodes surgiram no WordPress 2.5 (2008), os blocos no 5.0 (2018). Hoje, os blocos são a principal forma de inserir conteúdo dinâmico, mas os shortcodes continuam relevantes: são mais simples de desenvolver, não exigem conhecimentos de JavaScript e funcionam em qualquer editor, incluindo o Editor Clássico e construtores de páginas.

Um shortcode é uma etiqueta de texto que o WordPress substitui pelo resultado de uma função PHP ao renderizar a página. Ao contrário de um bloco Gutenberg, um shortcode não tem interface visual no editor: o gestor de conteúdo escreve [myshortcode] como texto e vê o HTML final no front-end.

Posso usar um shortcode dentro de outro shortcode?

Sim. Se a função de callback do shortcode exterior envolver o conteúdo aninhado em do_shortcode(), os shortcodes interiores funcionarão corretamente: [notice][current_year][/notice] produzirá um bloco estilizado com o ano atual. Sem do_shortcode(), o shortcode aninhado permanecerá como texto entre parênteses retos.

Os shortcodes aninhados são processados recursivamente: o WordPress percorre a string várias vezes até não restarem etiquetas por processar. Mas para que isto funcione, o shortcode exterior tem de chamar explicitamente do_shortcode($content). Caso contrário, a string [current_year] permanecerá como texto em vez de se transformar em "2026".

Porque é que o meu shortcode não funciona e aparece como texto entre parênteses retos?

Três razões comuns. Primeira: add_shortcode é chamado antes do hook init; mova o registo para dentro de add_action('init', ...). Segunda: um erro de digitação no nome da etiqueta, [my_shortcode] no editor, mas myshortcode está registado. Terceira: a função de callback usa echo em vez de return, pelo que o resultado vai para o topo da página e a localização do shortcode fica vazia.

O culpado mais frequente é o echo em vez de return na função de callback. O WordPress chama os manipuladores de shortcodes antes de emitir o conteúdo principal, por isso o resultado do echo atinge o buffer de saída antes do cabeçalho da página. Abra o código-fonte da página (Ctrl+U): se vir o HTML do shortcode mesmo no topo, antes de <html>, esse é exatamente o problema.

Preciso de escapar o output do shortcode?

Absolutamente. Um shortcode aceita atributos do editor, o que significa potencialmente de qualquer utilizador com permissões de autor ou editor. esc_html() para texto, esc_url() para links, esc_attr() para atributos HTML. A exceção é quando devolve intencionalmente markup HTML (como <div class="notice">). Mas mesmo aí, escape os atributos dentro do markup.

Sim, o escape é obrigatório para tudo o que venha de atributos de shortcodes ou de input do utilizador. Mesmo que hoje seja só você a inserir shortcodes, amanhã um gestor de conteúdo terá acesso de editor. esc_html() para texto, esc_url() para links, esc_attr() para atributos HTML protegem contra XSS acidental ou intencional.

Quantos shortcodes posso registar num site?

Não há limite técnico: $shortcode_tags é um array PHP normal, atingirá o limite de memória do servidor muito depois do que o bom senso dita. Na prática, depois de 15 a 20 shortcodes personalizados, vale a pena perguntar: será altura de migrar alguns deles para blocos Gutenberg? Mantenha shortcodes com lógica única (ofuscação de email, output condicional por função). Para shortcodes que apenas estilizam texto ([highlight]), é melhor usar um estilo de bloco ou uma classe CSS.

Tecnicamente, quantos quiser: o array $shortcode_tags não tem limite artificial. Na prática, mais de 20 a 25 shortcodes num site sugere que parte da lógica deveria ser migrada para blocos. Cada shortcode acrescenta sobrecarga de análise de conteúdo: antes do output, o WordPress itera sobre todo o array de etiquetas registadas e procura correspondências no texto do artigo.

Devo escrever os meus próprios shortcodes ou os plugins prontos são suficientes?

Um plugin pronto cobre a maioria das tarefas típicas: formulários, Contact Form 7, tabelas, TablePress, grelhas, qualquer construtor de páginas. Um shortcode personalizado é necessário quando a lógica é específica do seu site e não existe uma solução pronta: mostrar um campo personalizado exatamente naquele ponto da página, a data do próximo webinar a partir da base de dados, uma saudação personalizada com base na função do utilizador.

Resumindo: para funcionalidades padrão, use um plugin e não programe. Para lógica única, add_shortcode + functions.php ou um mini-plugin. O código em qualquer um dos exemplos acima tem menos de dez linhas. Depois de dominar estes três padrões (simples, com atributos, com conteúdo aninhado), cobrirá a grande maioria das tarefas para as quais se escrevem shortcodes personalizados.