Campos Personalizados (Custom Fields), tecnicamente conhecidos como Post Meta, são a funcionalidade que transforma o WordPress de uma plataforma simples de blog num poderoso Sistema de Gestão de Conteúdos (CMS). Permitem atribuir qualquer informação extra a um post, como “Classificação do Filme”, “Preço do Produto”, “Data do Evento” ou “ID do Vídeo Relacionado”.
Neste guia técnico para programadores (Edição 2026), não vamos apenas aprender a exibir campos. Vamos entender a arquitetura da Metadata API, aprender a escrever consultas eficientes e descobrir quando não usar campos personalizados.
Como ler e guardar post meta com get_post_meta()
O WordPress oferece um conjunto de funções para gerir metadados, conhecido como CRUD (Create, Read, Update, Delete).
Ler um campo com get_post_meta()
Está e a função mais usada.
// Sintaxe
$valor = get_post_meta( $post_id, $chave, $single );- $post_id: ID do Post (use
get_the_ID()dentro do loop). - $chave: O nome do campo na base de dados (ex: ‘preço_produto’).
- $single:
true: Retorna um valor único (string/int).false(padrão): Retorna um array de valores. Esta é uma armadilha comum!
Exemplo:
$preco = get_post_meta( get_the_ID(), 'preco_produto', true );
if ( $preco ) {
echo 'Preço: ' . esc_html( $preco ) . ' €';
}Criar ou atualizar um campo com update_post_meta()
Está função é inteligente: se o campo não existir, cria-o. Se existir, atualiza-o.
update_post_meta( $post_id, 'preco_produto', '99.00' );Se guardar um array, o WordPress irá serializá-lo automaticamente:
$dados = ['cor' => 'vermelho', 'tamanho' => 'XL'];
update_post_meta( $post_id, 'variantes', $dados );
// Guardado na BD como: a:2:{s:3:"cor";s:8:"vermelho"...}Apagar um campo com delete_post_meta()
delete_post_meta( $post_id, 'preco_produto' );Arrays serializados em post meta e desempenho
Por padrão, get_post_meta() com $single = false retorna um array de arrays, o que é pouco intuitivo.
Se tiver um campo “cor” com o valor “azul”:
$val = get_post_meta( $id, 'cor', false );
// Retorna: Array ( [0] => "azul" )Portanto, em 99% dos casos, usamos $single = true.
Porque os arrays serializados tornam o SQL lento
O WordPress serializa automaticamente arrays é objetos PHP na base de dados. Isto é conveniente, MAS: Não pode pesquisar ou ordenar eficientemente por dados serializados em SQL.
Se guardar dados como ['idade' => 25, 'cidade' => 'Lisboa'] num único campo meta, uma consulta SQL à procura de “pessoas de Lisboa” teria de usar um LIKE %Lisboa% lento, o que mata o desempenho em grandes bases de dados.
Regra de Ouro: Se precisar de pesquisar ou ordenar por algo (ORDER BY), guarde-o num campo meta separado, não dentro de um array.
Filtrar posts por campo personalizado com meta_query
O verdadeiro poder manifesta-se em WP_Query. Pode obter posts com base nos valores dos seus campos.
Como filtrar posts por valor numérico com meta_query
$args = [
'post_type' => 'produto',
'meta_query' => [
[
'key' => 'preco',
'value' => 100,
'compare' => '>',
'type' => 'NUMERIC' // Importante para ordenação numérica correta!
]
]
];
$query = new WP_Query( $args );Combinar vários campos em meta_query com AND ou OR
$args = [
'post_type' => 'produto',
'meta_query' => [
'relation' => 'AND', // ou 'OR'
[
'key' => 'preco',
'value' => 100,
'compare' => '>',
'type' => 'NUMERIC'
],
[
'key' => 'cor',
'value' => 'vermelho'
]
]
];Aviso de Desempenho: Pedidos meta_query geram JOINs para a tabela wp_postmeta. CADA critério adicional é outro JOIN. Com milhões de posts, isto pode ser extremamente lento. Se o seu site estiver lento, verifique se está a abusar de meta_query. Nesses casos, considere tabelas de base de dados personalizadas.
Exibir campos personalizados com ACF ou PHP puro
O plugin Advanced Custom Fields (ACF) é o padrão da indústria. Simplifica a criação de UI para campos no painel de administração.
Ler um campo ACF com get_field()
$preco = get_field('preco'); // Faz automaticamente get_post_metaMetabox sem plugin com add_meta_box()
Se não quiser dependência de plugins, pode criar uma metabox manualmente usando add_meta_box(), mas requer código significativo (formulário HTML, nonce, guardar save_post).
Em 2026, uma abordagem híbrida é comum: use ACF para criar campos (UI), mas obtenha-os via get_post_meta() no código se quiser “pureza” e evitar a sobrecarga da API do ACF em casos simples.
Ocultar campos personalizados com prefixo underscore
Já notou que alguns campos não aparecem na lista “Campos Personalizados” no editor de posts? Isso acontece quando o nome da chave começa com um sublinhado _.
preço-> Visível para o utilizador na UI padrão._preco-> Oculto (Protegido).
Plugins como Yoast SEO ou WooCommerce usam _ (ex: _yoast_wpseo_title) para que o utilizador não estrague esses dados manualmente. Como programador, também deve usar está convenção para dados do sistema.
Sanitizar e escapar campos personalizados no WordPress
Está e a secção mais importante. Nunca confie em dados, mesmo da base de dados.
Sanitizar dados ao guardar com sanitize_text_field()
Antes de colocar dados na base de dados (update_post_meta), limpe-os.
$novo_preco = sanitize_text_field( $_POST['preco'] );
update_post_meta( $post_id, 'preco', $novo_preco );Outras funções úteis: sanitize_email(), absint() (para inteiros).
Escapar a saída com esc_html, esc_url e esc_attr
Antes de enviar dados para o navegador (echo), garanta que não contêm JS malicioso (XSS).
// MAU
echo get_post_meta($id, 'url', true);
// BOM
echo esc_url( get_post_meta($id, 'url', true) );
// TEXTO
echo esc_html( get_post_meta($id, 'cidade', true) );
// ATRIBUTOS HTML
echo '<div class="' . esc_attr( $classe ) . '">';Guardar dados do Gutenberg em atributos de bloco ou em post meta?
Em 2026, ao usar o Block Editor (Gutenberg), surgé a questão: Onde guardar dados? Em atributos de bloco ou post meta?
- Atributos de Bloco: Guardados no conteúdo do post (HTML). Rápido de ler ao renderizar, mas impossível de consultar em SQL (não pode fazer “mostrar posts com um bloco que tem cor vermelha”).
- Post Meta: Guardados na tabela
wp_postmeta. Mais lento (requer consulta separada), mas permite filtragem é ordenação (ex: em arquivos).
Melhor Prática: Se os dados dizem respeito à aparência de um elemento específico na página -> Atributo de Bloco. Se os dados descrevem o post inteiro e quer filtrar por eles -> Post Meta.
Também pode combinar ambos: Um Bloco Gutenberg pode guardar os seus atributos em Post Meta para que fiquem acessíveis a WP_Query.
Resumo
A função get_post_meta() é apenas a ponta do iceberg. Para ser um programador WordPress consciente em 2026:
- Entenda a diferença entre
$single=trueefalse. - Evite serializar dados pelos quais precisa de pesquisar.
- Cuidado com o desempenho de
meta_query(índices da base de dados). - Use sempre (SEMPRE) funções de escaping (
esc_html,esc_url). - Escolha sabiamente entre atributos de bloco e campos meta.







