
📋 Folha de dicas completa do WordPress
Abriu o functions.php e esqueceu-se de como ligar a barra lateral? Acontece a todos os que programam um tema WordPress à mão. Precisa de uma página de consulta, não de dez separadores do developer.wordpress.org.
Aqui encontra os elementos essenciais do desenvolvimento WordPress: 13 ficheiros de template e a hierarquia para os escolher, o Loop básico, tags de inclusão e parâmetros do bloginfo(), depois hooks e filtros, tags condicionais, enfileiramento de scripts, shortcodes, WP_Query, escape de dados, REST API e comandos WP-CLI. Todos os exemplos de código funcionam. Mantenha este separador aberto durante o desenvolvimento e consulte-o à medida que avança.
💡 Visão geral rápida:
- Adicione esta página aos favoritos e mantenha-a aberta num separador próprio enquanto constrói o seu tema.
- Comece pela secção "Anatomia de um tema": crie os ficheiros do tema a partir da lista antes de escrever código.
- Copie o WordPress Loop básico para o
index.phpe envolva-o com as tags de inclusão do cabeçalho, barra lateral e rodapé. - Coloque as tags
bloginfo()eget_bloginfo()da tabela diretamente nos templates, verificando a coluna "O que produz". - Antes de publicar, reveja as regras do
style.css: valide o CSS, minimize e adicione estilos para impressão. - Mais abaixo na página, a referência: hierarquia de templates, hooks e filtros, tags condicionais, enfileiramento de scripts, shortcodes,
WP_Query, escape, REST API e WP-CLI.
Anatomia de um tema WordPress

Um tema WordPress é um conjunto de ficheiros PHP unidos por uma lógica comum e regidos pela hierarquia de templates. O componente chave: o style.css, que trata do estilo visual e serve simultaneamente como identificador do tema no admin. Mas a base de qualquer tema clássico são os templates PHP: cada um trata da sua própria secção da página e é chamado pela ordem definida na hierarquia do WordPress.
Para criar um tema padrão precisa dos seguintes ficheiros, treze no total, cada um a cobrir uma zona específica do site:
- header.php, a secção
<head>e o topo da página: metadados, título do site, inclusão dostyle.css, tag de abertura<body>. - index.php, o template principal, ponto de entrada. Monta os outros ficheiros numa página unificada através de tags de inclusão. Se não existir um template especializado, o WordPress recorre ao
index.php. - sidebar.php, a barra lateral: widgets, categorias, pesquisa, menu secundário.
- footer.php, o rodapé: direitos de autor, links sociais, scripts de analytics, tags de fecho
</body></html>. - page.php, template para páginas (conteúdo estático, "Sobre nós", "Contacto").
- single.php, template para um artigo individual do blog.
- comments.php, bloco de comentários e formulário de submissão.
- 404.php, página de erro 404. Se este ficheiro não existir, o WordPress mostra uma mensagem padrão do sistema, o que é pior para o visitante.
- search.php, template para resultados de pesquisa.
- searchform.php, formulário de pesquisa (em temas clássicos; os modernos usam frequentemente um widget).
- archive.php, template para arquivos: categorias, tags, arquivos por data.
- functions.php, o coração funcional do tema: hooks personalizados, enfileiramento de scripts e estilos, registo de menus, áreas de widgets, tipos de conteúdo personalizados. Tudo o que adiciona funcionalidade ao tema reside aqui.
- style.css, o único ficheiro não PHP da lista, mas sem ele o tema não existe: guarda o cabeçalho do tema e define a aparência do site.
Pode funcionar com menos templates, por exemplo, index.php + style.css já formam um tema mínimo. Mas para um site completo, é melhor manter todos os treze: cada ficheiro é adaptado à sua própria tarefa, e o próprio WordPress escolhe o correto pela hierarquia. Um index.php típico tem este aspeto:
1 <?php get_header(); ?> 2 3 <!-- Main content, including the Loop --> 4 5 <?php get_sidebar(); ?> 6 <?php get_footer(); ?>
Passemos ao fragmento de código mais importante, sem o qual nenhum artigo é exibido.
O WordPress Loop
O Loop é o mecanismo central para a produção de conteúdo. Sem ele, teria de codificar manualmente a exibição de cada artigo e de cada página no template do tema. O Loop faz exatamente o que o nome promete: percorre todos os artigos que correspondem à consulta atual e aplica a cada um a marcação HTML/PHP que especificou.
Sintaxe básica do Loop:
1 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 2 <!-- HTML markup and template tags for each post --> 3 <?php endwhile; endif; ?>
O have_posts() verifica se há artigos para produzir. Se houver, o the_post() inicializa o ponteiro interno do WordPress para o artigo atual, após o que dezenas de template tags ficam disponíveis dentro do Loop: the_title() para o título, the_content() para o texto do artigo, the_permalink() para o link, the_excerpt() para o excerto e muitas outras.
O Loop é normalmente colocado no index.php para produzir uma lista de artigos, mas nada o impede de o usar no single.php, page.php ou archive.php, a lógica é a mesma, apenas o contexto difere. Dentro do Loop, adicione quaisquer wrappers HTML e tags PHP, o WordPress aplicá-los-á a cada artigo por sua vez.
Exemplo prático, produzir o título e a data de cada artigo:
1 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 2 <article> 3 <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> 4 <time><?php echo get_the_date(); ?></time> 5 </article> 6 <?php endwhile; endif; ?>
Agora, sobre como o Loop interage com o resto do tema, através das tags de inclusão.
Tags de inclusão de templates
As tags de inclusão são funções PHP que carregam o conteúdo de um ficheiro do tema para dentro de outro. Formam o esqueleto de um index.php típico: cabeçalho, conteúdo, barra lateral, rodapé. Quatro funções básicas:
<?php get_header(); ?>, inclui oheader.php. Normalmente a primeira linha noindex.phpe em qualquer outro template que precise de cabeçalho.<?php get_sidebar(); ?>, inclui osidebar.php. Se a barra lateral não for necessária, basta remover a chamada.<?php get_footer(); ?>, inclui ofooter.php. Sempre no final do template, fecha a página.<?php comments_template(); ?>, inclui ocomments.php. Colocado dentro dosingle.php, após a produção do conteúdo do artigo.
Todas as quatro funções procuram ficheiros na pasta do tema ativo. Se o ficheiro não existir, o WordPress simplesmente não produz nada (exceto get_header() e get_footer(), cuja ausência quebrará o layout).
O próximo nível, tags que não se limitam a incluir ficheiros, mas extraem dados da base de dados.
Tags bloginfo

As tags bloginfo() extraem informações sobre o site da base de dados do WordPress, as mesmas informações que preenche em Definições → Geral e no perfil de utilizador. A função devolve uma string e produz-a imediatamente no ecrã. Os parâmetros mais usados:
Parâmetro | O que produz |
|---|---|
| Título do site |
| URL do site |
| Descrição curta (descrição do site) |
| Charset (padrão UTF-8) |
| URL do |
| Versão do WordPress instalada |
| Idioma do site |
| URL do feed RSS (RSS 0.92) |
| URL do feed RSS (RSS 2.0) |
Isto é apenas a ponta do icebergue, a lista completa de parâmetros está na documentação do WordPress.
Get_bloginfo(), quando precisa de guardar em vez de produzir
Para os casos em que a informação do site precisa de ser usada em código, em vez de apenas mostrada na página, use a função get_bloginfo():
1 <?php $info = get_bloginfo( $show, $filter ); ?>
$show, a palavra-chave. Os valores suportados são'name'(título),'url'(endereço),'description'(descrição curta),'admin_email'(email do admin) e outros; lista completa na documentação.$filter, modo de filtragem:'raw'(valor "tal como está", padrão) ou'display'(o valor é passado pelowptexturize(), converte aspas, travessões, caracteres).
Exemplo: obter a descrição do site e produzi-la com um prefixo:
1 <?php $site_description = get_bloginfo( 'description' ); ?> 2 <?php echo 'Your site tagline: ' . esc_html( $site_description ); ?>
Resultado: «Your site tagline: Best premium WordPress themes».
Além do bloginfo, o WordPress dispõe de um vasto sistema de template tags: tags gerais, tags de autor, tags de miniatura, tags de categoria, tags de link, todas funcionam dentro e fora do Loop, e as combinações oferecem controlo total sobre a saída de conteúdo.
Folha de estilos do tema
O style.css desempenha duas funções. Primeiro, identificação: o cabeçalho no topo do ficheiro indica ao WordPress o nome do tema, autor, versão e licença. Segundo, visual: todas as regras CSS que controlam a aparência do site. Um cabeçalho padrão tem este aspeto:
1 /* 2 Theme Name: Theme Name 3 Theme URI: https://www.example.com/theme 4 Author: Your Name 5 Author URI: https://www.example.com/ 6 Description: Responsive WordPress theme with support for... 7 Version: 1.0 8 License: GNU General Public License v2 or later 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html 10 Tags: responsive, two-columns, right-sidebar, custom-header 11 Text Domain: mythemename 12 */
Boas práticas ao trabalhar com o style.css:
- Siga as normas de codificação CSS do WordPress, um estilo consistente simplifica a manutenção.
- Valide o CSS através do validador do W3C.
- Minimize o CSS em produção, mas mantenha uma fonte legível para desenvolvimento.
- Adicione estilos de impressão (
@media print), muitos leitores imprimem artigos. - Estilize todos os elementos HTML padrão que possam aparecer no conteúdo dos artigos.
Hierarquia de templates do WordPress
Para cada pedido, o próprio WordPress decide qual ficheiro PHP do tema incluir, esta é a hierarquia de templates. Uma regra: do ficheiro mais específico para o mais geral, com o index.php como último recurso para qualquer ramo. Conhecer a ordem elimina a questão «porque é que a minha edição do single.php não aparece na página de categoria».
1 Single post → single-{post_type}-{slug}.php → single-{post_type}.php → single.php → singular.php → index.php 2 Page → {template from editor}.php → page-{slug}.php → page-{id}.php → page.php → singular.php → index.php 3 Category → category-{slug}.php → category-{id}.php → category.php → archive.php → index.php 4 Archive → archive-{post_type}.php → archive.php → index.php 5 Search → search.php → index.php 6 404 error → 404.php → index.php 7 Front page → front-page.php → home.php → index.php
O WordPress utiliza o primeiro ficheiro existente, da esquerda para a direita. Assim, o single-product.php irá sobrepor-se ao single.php apenas para entradas do tipo de conteúdo product, deixando o resto intacto.
Hooks: ações e filtros
Os hooks são pontos de extensão do WordPress: permitem-lhe ligar-se a funcionalidades do núcleo sem editar os seus ficheiros. As ações executam um efeito secundário (enfileirar um script, enviar um email), os filtros recebem um valor, modificam-no e devem devolvê-lo. Um return esquecido num filtro é a causa mais comum de conteúdo vazio.
1 // Registration 2 add_action( 'hook_name', 'callback', 10, 1 ); // priority, number of arguments 3 add_filter( 'hook_name', 'callback', 10, 1 ); 4 5 // Execution (in core or your code) 6 do_action( 'hook_name', $arg ); // action: returns nothing 7 apply_filters( 'hook_name', $value, $arg ); // filter: RETURNS value 8 9 // Removal (priority must match the one used when adding) 10 remove_action( 'hook_name', 'callback', 10 );
Exemplo, adicionar um parágrafo ao final de cada artigo:
1 add_filter( 'the_content', 'my_append_note', 20 ); 2 function my_append_note( $content ) { 3 return $content . '<p>Thanks for reading!</p>'; // without return content disappears 4 }
Hooks principais do tema:
after_setup_theme, registar suporte a funcionalidades (add_theme_support()), menus, tamanhos de miniaturas.wp_enqueue_scripts, o único local correto para enfileirar CSS e JS do frontend.init, inicialização precoce: registar tipos de conteúdo e shortcodes.the_content, filtrar o HTML do artigo antes da saída.
Uma prioridade mais baixa é executada mais cedo (padrão 10). Para que um callback receba mais do que um argumento, aumente o quarto parâmetro accepted_args.
Tags condicionais
As tags condicionais são funções que devolvem true ou false dependendo da página que está atualmente aberta. Elas constroem a lógica de «mostrar barra lateral aqui, mas não na 404».
1 is_home() // blog post feed 2 is_front_page() // site front page 3 is_single() // single post 4 is_page() // single page 5 is_singular() // any single post/page/CPT 6 is_archive() // any archive 7 is_category() // category archive 8 is_search() // search results page 9 is_404() // 404 error page 10 is_user_logged_in() // user is logged in 11 is_admin() // request is in admin (NOT "user is administrator")
Principal armadilha: as tags condicionais de consulta (is_single, is_page, is_home e outras) só funcionam depois de a consulta principal estar formada, ou seja, dentro dos ficheiros de template e do Loop ou a partir do hook template_redirect. Chamá-las cedo no functions.php ou no init é demasiado cedo: o WordPress emitirá _doing_it_wrong() e devolverá um resultado incorreto. As exceções são is_admin() e is_user_logged_in(), que não dependem da consulta e estão disponíveis mais cedo. E lembre-se: is_admin() verifica o contexto (admin vs frontend), não a função; para a função utilize current_user_can( 'manage_options' ).
Enfileirar scripts e estilos
A tentação de escrever <link> e <script> diretamente no header.php é forte, mas é um erro: perde a gestão de dependências, o versionamento para invalidação de cache, as estratégias de defer/async e a proteção contra carregamento duplo (dois plugins podem facilmente enfileirar o jQuery duas vezes). O caminho correto é a fila do WordPress no hook wp_enqueue_scripts.
1 add_action( 'wp_enqueue_scripts', 'my_theme_assets' ); 2 function my_theme_assets() { 3 // Theme style with version from style.css header 4 wp_enqueue_style( 5 'my-theme', 6 get_stylesheet_uri(), 7 array(), 8 wp_get_theme()->get( 'Version' ) 9 ); 10 11 // Script with dependency and modern syntax (WP 6.3+) 12 wp_enqueue_script( 13 'my-app', 14 get_theme_file_uri( 'assets/js/app.js' ), 15 array( 'jquery' ), // dependencies 16 '1.0.0', // version → cache busting 17 array( 18 'in_footer' => true, 19 'strategy' => 'defer', 20 ) 21 ); 22 }
A partir do WordPress 6.3, o último parâmetro de wp_enqueue_script() é um array $args (in_footer, strategy), embora a forma antiga com o booleano true para o footer ainda funcione. Para o frontend use wp_enqueue_scripts, para a administração use admin_enqueue_scripts, para a página de login use login_enqueue_scripts.
Shortcodes
Os shortcodes transformam uma entrada curta entre parênteses retos em HTML arbitrário, conveniente para botões, galerias e formulários dentro do conteúdo. O handler deve devolver uma string, não a emitir através de echo, caso contrário o resultado «saltará» para o início da página.
1 add_shortcode( 'btn', 'my_button_shortcode' ); 2 function my_button_shortcode( $atts, $content = null, $tag = '' ) { 3 $a = shortcode_atts( 4 array( 'url' => '#', 'label' => 'Button' ), 5 $atts, 6 $tag 7 ); 8 return sprintf( 9 '<a class="btn" href="%s">%s</a>', 10 esc_url( $a['url'] ), // escape on output 11 esc_html( $a['label'] ) 12 ); 13 } 14 // Usage in post: [btn url="https://example.com" label="Buy"]
O shortcode_atts() sobrepõe os atributos do utilizador aos valores padrão. Se precisar de executar shortcodes dentro de uma string ou template, envolva-os em do_shortcode(), mas para chamar a sua própria função, chame-a diretamente, sem o intermediário.
WP_Query e consultas personalizadas
O WP_Query é a classe para qualquer seleção de artigos: últimas notícias na barra lateral, coleção de categoria, feed de tipo de conteúdo personalizado. Após o seu loop, chame sempre wp_reset_postdata(), caso contrário as tags de template mais abaixo na página obterão o artigo errado.
1 $q = new WP_Query( array( 2 'post_type' => 'post', 3 'posts_per_page' => 5, 4 'category_name' => 'news', 5 'orderby' => 'date', 6 'order' => 'DESC', 7 ) ); 8 9 if ( $q->have_posts() ) { 10 while ( $q->have_posts() ) { 11 $q->the_post(); 12 the_title( '<h3>', '</h3>' ); 13 } 14 wp_reset_postdata(); // restore global $post 15 }
Para modificar a consulta da página principal (por exemplo, número de artigos na página inicial), não use o obsoleto query_posts(), ele executa uma consulta extra à base de dados e quebra a paginação. A abordagem correta é o hook pre_get_posts, que modifica a consulta antes da sua execução:
1 add_action( 'pre_get_posts', 'my_main_query' ); 2 function my_main_query( $query ) { 3 if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) { 4 $query->set( 'posts_per_page', 12 ); 5 } 6 }
Segurança: escape e sanitização
A regra de ouro do WordPress: sanitizar na entrada, escapar na saída, validar em todo o lado. Qualquer dado do utilizador é limpo antes de ser guardado na base de dados e escapado antes da saída em HTML, mesmo que já tenha sido limpo.
1 // Escaping ON OUTPUT 2 echo esc_html( $text ); // text inside tag 3 echo esc_attr( $value ); // attribute value 4 echo esc_url( $href ); // href/src links 5 echo wp_kses_post( $rich_html ); // safe HTML set for content 6 7 // Sanitization ON INPUT (before writing to DB) 8 $clean = sanitize_text_field( $_POST['name'] ); 9 $email = sanitize_email( $_POST['email'] ); 10 $num = absint( $_POST['count'] );
Proteja formulários e ações com nonces, tokens únicos contra CSRF:
1 // In form: 2 wp_nonce_field( 'my_save_action', 'my_nonce' ); 3 4 // During processing: 5 if ( ! isset( $_POST['my_nonce'] ) || 6 ! wp_verify_nonce( $_POST['my_nonce'], 'my_save_action' ) ) { 7 return; // request rejected 8 }
Na prática, a maioria das vulnerabilidades em temas e plugins são precisamente falhas de escape na saída. Crie o hábito: nem uma única variável vai para HTML sem esc_*.
API REST do WordPress
A API REST devolve dados do site em formato JSON, sendo usada por aplicações móveis, frontends headless e integrações. O endereço base é /wp-json/wp/v2/.
1 GET /wp-json/wp/v2/posts // posts 2 GET /wp-json/wp/v2/pages // pages 3 GET /wp-json/wp/v2/media // media files 4 GET /wp-json/wp/v2/users // users 5 GET /wp-json/wp/v2/posts/123 // single post 6 GET /wp-json/wp/v2/posts?per_page=5&search=theme&_embed
As rotas personalizadas são registadas no hook rest_api_init. O parâmetro permission_callback é obrigatório; sem ele, o WordPress emitirá um aviso. Para leitura pública, utilize '__return_true'.
1 add_action( 'rest_api_init', function () { 2 register_rest_route( 'myplugin/v1', '/items/(?P<id>\d+)', array( 3 'methods' => 'GET', 4 'callback' => 'my_get_item', 5 'permission_callback' => '__return_true', 6 ) ); 7 } );
WP-CLI: comandos à mão
O WP-CLI gere o site a partir do terminal, de forma mais rápida e fiável do que clicar no admin, especialmente ao manter vários sites. Comandos mais comuns:
1 wp core update # update WordPress core 2 wp core version # what version is installed 3 wp plugin install akismet --activate # install and activate plugin 4 wp plugin list # plugin list with status and version 5 wp theme activate twentytwentyfive # switch active theme 6 wp db export backup.sql # database dump to file 7 wp search-replace 'old.com' 'new.com' --dry-run # always dry run first 8 wp user create bob [email protected] --role=editor # create user 9 wp cache flush # flush object cache
O wp search-replace compreende dados serializados, pelo que altera com segurança o domínio ao migrar um site, ao contrário de uma consulta SQL direta que quebra a serialização. Antes de qualquer operação perigosa, faça wp db export.
Temas clássicos e de blocos em 2026
Em meados de 2026 (versão atual: WordPress 7.0 «Armstrong», PHP 8.3+ recomendado), os temas PHP clássicos ainda são totalmente suportados e continuam a ser o tipo mais difundido. Mas todas as novas ferramentas do núcleo desenvolvem temas de blocos e edição completa do site (Full Site Editing): theme.json em vez de parte das configurações do functions.php, templates HTML em vez de PHP. O Loop, bloginfo(), as tags condicionais e os hooks continuam relevantes em temas híbridos e em quaisquer fragmentos PHP dentro de temas FSE, pelo que esta folha de consulta não perde valor. O caminho prático em 2026 é uma base clássica com suporte direcionado a blocos onde for realmente necessário.
⁉️🤔 Perguntas frequentes
É obrigatório criar todos os 13 ficheiros para um tema?
Não, o tema mínimo funcional é
index.php+style.css. Mas para um site completo é melhor manter o conjunto completo: cada ficheiro dá ao WordPress a capacidade de escolher o modelo ideal. Por exemplo, sem osingle.php, um artigo será renderizado através doindex.phpe perderá o bloco de comentários.
Qual é a diferença entre get_bloginfo() e bloginfo()?
bloginfo() emite o valor imediatamente para o ecrã (echo). get_bloginfo() devolve uma string para uma variável, permitindo processá-la, acrescentar-lhe algo ou usá-la dentro de outra expressão antes da saída final.
Onde coloco o Loop se a página tiver vários tipos de conteúdo?
O Loop pode ser executado várias vezes. Cenário típico: um Loop para a lista principal de artigos, um segundo para um widget de «últimas notícias» na barra lateral. Antes do segundo Loop, reponha o ponteiro através de wp_reset_postdata(), caso contrário o código seguinte na página obterá o contexto de artigo errado.
Esta folha de consulta funciona para temas de blocos (FSE)?
Parcialmente. Os temas de blocos (Full Site Editing) usam
theme.jsonem vez defunctions.phppara muitas definições e modelos em HTML em vez de PHP. Mas o Loop,bloginfo()e as tags de inclusão continuam a ser relevantes para temas híbridos e quaisquer modelos PHP dentro de temas FSE.
O que fazer se o functions.php se tornar demasiado grande?
Divida a lógica em ficheiros separados e inclua-os a partir do
functions.phpatravés derequire_onceouinclude. Por exemplo:require_once get_template_directory() . '/inc/custom-post-types.php';. Isto melhora a legibilidade e simplifica a manutenção, uma prática recomendada para qualquer tema com mais de 20 a 30 hooks.
Qual é a diferença entre uma ação e um filtro?
Uma ação executa um efeito colateral e não devolve nada (enfileirar um script, enviar um email). Um filtro recebe um valor, modifica-o e deve devolvê-lo; um
returnesquecido num filtro anulará o conteúdo. São registados de forma idêntica:add_action()eadd_filter().
Porque é que o is_single() não funciona no functions.php?
As tags condicionais de consulta só estão disponíveis depois de a consulta principal estar formada, ou seja, em ficheiros de modelo ou a partir do hook
template_redirect. No início dofunctions.php, a consulta ainda não está pronta, pelo que o WordPress emitirá_doing_it_wrong(). Apenasis_admin()eis_user_logged_in()funcionam sem dependência de consulta.
O que ter à mão ao desenvolver em WordPress
Esta folha de consulta é a estrutura a partir da qual o desenvolvimento em WordPress começa. Os ficheiros do tema e a hierarquia de modelos, o Loop, as tags de inclusão e o bloginfo() montam o tema, enquanto hooks e filtros, tags condicionais, enfileiramento de scripts, shortcodes, WP_Query, escape, REST API e WP-CLI cobrem a grande maioria das tarefas rotineiras. O resto é prática e documentação.
Para um estudo aprofundado, o manual de desenvolvimento de temas em developer.wordpress.org é o primeiro endereço. A referência de tags de modelo com centenas de funções para todas as ocasiões também está lá. Se está a passar de um layout HTML para um tema finalizado, comece com o guia passo a passo para criar um tema WordPress a partir de HTML, onde o Loop e as tags são explicados em contexto de combate, do layout ao tema funcional.
Guarde esta folha de consulta nos favoritos e mantenha-a à mão durante o desenvolvimento.
Que tag ou hook consulta com mais frequência? Escreva nos comentários que tarefa de WordPress encontrou e partilhe o seu caso de uso, a troca de experiência ao vivo vale por uma dúzia de guias oficiais.



