
⚡ 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:
echoem vez dereturn, 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):
1 function 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 chamaradd_shortcodediretamente num ficheiro de plugin, pode ser executado antes de o WordPress estar totalmente inicializado. A forma correta é envolvê-lo num hook:
1 add_action( 'init', 'my_register_shortcodes' ); 2 3 function 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 comomyplugin_ou uma abreviatura única resolve o problema. Nos exemplos abaixo uso o prefixomysite_; 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:
1 add_shortcode( 'mysite_current_year', 'mysite_display_current_year' ); 2 3 function 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:
1 add_shortcode( 'mysite_cta', 'mysite_cta_button' ); 2 3 function 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:
1 add_shortcode( 'mysite_notice', 'mysite_notice_box' ); 2 3 function 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 9 defined( 'ABSPATH' ) || exit; 10 11 class 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 39 MySite_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 | 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
echoem vez dereturnna função de callback. O WordPress chama os manipuladores de shortcodes antes de emitir o conteúdo principal, por isso o resultado doechoatinge 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_tagsnã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.



