Quer estilizar todas as páginas em /services/ de forma diferente? Aprenda como injetar slugs pais na função body_class() do WordPress.
PT-PT

Adicionar slug da página pai às classes do body (snippet WordPress)

5.00 /5 - (31 votes )
Última verificação: 1 de março de 2026
Experiência: 10+ anos de experiência
Índice

Os temas WordPress usam body_class() para adicionar classes CSS úteis à tag <body>. No entanto, por padrão, não indica claramente se uma página é filha de uma seção pai específica.

Se você tem uma estrutura como:

  • /services/
  • /services/web-design/
  • /services/seo/

Você pode querer estilizar todas as páginas em “Services” com um fundo azul. As classes padrão como page-id-123 são irritantes de manter.

O problema: Targeting CSS limitado

A função padrão body_class() do WordPress adiciona classes como:

  • page-id-123 (numérico, difícil de lembrar)
  • page-template-default (genérico)
  • page (muito amplo)

Mas não lhe diz:

  • A que seção a página pertence
  • A hierarquia da página (relação pai/filho)
  • O slug da página (identificador legível)

Isso torna o targeting CSS difícil. Você acaba com código como:

/* Mau: Difícil de manter */
.page-id-123,
.page-id-124,
.page-id-125 {
    background: blue;
}

Cada vez que você adiciona uma nova página, precisa atualizar seu CSS. Isso não escala.

A solução: Adicionar slugs pais às classes do body

Ao adicionar slugs da página pai à classe do body, você pode direcionar seções inteiras com uma única regra CSS. Isso torna sua folha de estilos sustentável e escalável.

O snippet completo

Adicione esta versão aprimorada ao seu functions.php:

/**
 * Add page slugs and parent slugs to body classes
 *
 * Adds:
 * - Current page slug
 * - Parent page slug (if exists)
 * - Grandparent page slug (if exists)
 * - All ancestor slugs
 *
 * @param array $classes Existing body classes
 * @return array Modified classes array
 */
function wppoland_add_slug_body_class( $classes ) {
    global $post;

    if ( ! isset( $post ) || ! is_page() ) {
        return $classes;
    }

    // 1. Add current page slug
    $classes[] = 'page-slug-' . sanitize_html_class( $post->post_name );

    // 2. Add parent page slug (if exists)
    if ( $post->post_parent ) {
        $parent = get_post( $post->post_parent );
        if ( $parent ) {
            $classes[] = 'parent-' . sanitize_html_class( $parent->post_name );

            // 3. Add grandparent slug (if exists)
            if ( $parent->post_parent ) {
                $grandparent = get_post( $parent->post_parent );
                if ( $grandparent ) {
                    $classes[] = 'grandparent-' . sanitize_html_class( $grandparent->post_name );
                }
            }

            // 4. Add all ancestor slugs (recursive)
            $ancestors = get_post_ancestors( $post->ID );
            foreach ( $ancestors as $ancestor_id ) {
                $ancestor = get_post( $ancestor_id );
                if ( $ancestor ) {
                    $classes[] = 'ancestor-' . sanitize_html_class( $ancestor->post_name );
                }
            }
        }
    }

    // 5. Add template hierarchy classes
    $template = get_page_template_slug( $post->ID );
    if ( $template ) {
        $template_slug = str_replace( '.php', '', basename( $template ) );
        $classes[] = 'template-' . sanitize_html_class( $template_slug );
    }

    return $classes;
}
add_filter( 'body_class', 'wppoland_add_slug_body_class' );

Resultado: Classes do body aprimoradas

Agora sua tag <body> incluirá:

<body class="page page-id-123 page-slug-web-design parent-services ancestor-services ...">

Classes adicionadas:

  • page-slug-web-design - Slug da página atual
  • parent-services - Slug do pai direto
  • grandparent-company - Slug do avô (se existir)
  • ancestor-services - Todos os slugs ancestrais
  • template-custom - Nome do arquivo template (se personalizado)

Exemplos de uso

Exemplo 1: Estilizar todas as páginas de serviços

/* Fundo azul para TODAS as páginas de serviços */
body.parent-services {
    background-color: #eef;
}

/* Estilo específico para cabeçalho de serviços */
body.parent-services .site-header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* Rodapé da seção de serviços */
body.parent-services .site-footer {
    border-top: 3px solid #667eea;
}

Exemplo 2: Layouts diferentes por seção

/* Layout largura total para documentação */
body.parent-documentation .content-area {
    max-width: 100%;
    padding: 0;
}

/* Layout barra lateral para blog */
body.parent-blog .content-area {
    max-width: 1200px;
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 2rem;
}

Técnicas avançadas e extensões

Classes condicionais baseadas em funções de usuário

Uma extensão particularmente útil é adicionar classes baseadas na função do usuário. Isso permite definir estilos diferentes para administradores, editores ou usuários conectados:

/**
 * Adiciona classes específicas de funções de usuário
 *
 * @param array $classes Classes existentes do body
 * @return array Classes modificadas
 */
function wppoland_add_user_role_body_class( $classes ) {
    if ( is_user_logged_in() ) {
        $current_user = wp_get_current_user();

        // Usuário conectado
        $classes[] = 'logged-in';

        // Adicionar função do usuário
        if ( ! empty( $current_user->roles ) ) {
            foreach ( $current_user->roles as $role ) {
                $classes[] = 'user-role-' . sanitize_html_class( $role );
            }
        }

        // Nome de usuário para estilos personalizados
        $classes[] = 'user-id-' . get_current_user_id();
    } else {
        $classes[] = 'visitor';
    }

    return $classes;
}
add_filter( 'body_class', 'wppoland_add_user_role_body_class' );

Exemplo de uso:

/* Exibir informações de debug específicas para admin */
body.user-role-administrator .debug-panel {
    display: block;
    position: fixed;
    bottom: 0;
    left: 0;
    background: rgba(255, 0, 0, 0.8);
    color: white;
    padding: 10px;
    font-size: 12px;
    z-index: 9999;
}

/* Saudar usuários conectados */
body.logged-in .welcome-message::before {
    content: 'Bem-vindo de volta, ' attr(data-username) '!';
}

Classes para Custom Post Types e Taxonomias

Ao trabalhar com Custom Post Types, geralmente é útil adicionar o próprio post type como classe para permitir estilização específica:

/**
 * Adiciona classes específicas de CPT e Taxonomias
 *
 * @param array $classes Classes existentes do body
 * @return array Classes modificadas
 */
function wppoland_add_cpt_taxonomy_body_class( $classes ) {
    // Detecção de Custom Post Type
    if ( is_singular() ) {
        $post_type = get_post_type();
        if ( $post_type !== 'post' && $post_type !== 'page' ) {
            $classes[] = 'single-cpt-' . sanitize_html_class( $post_type );
            $classes[] = 'cpt-' . sanitize_html_class( $post_type );
        }
    }

    // Classes de Taxonomia Customizada
    if ( is_tax() || is_category() || is_tag() ) {
        $term = get_queried_object();
        if ( $term ) {
            $classes[] = 'taxonomy-' . sanitize_html_class( $term->taxonomy );
            $classes[] = 'term-' . sanitize_html_class( $term->slug );
            $classes[] = 'term-id-' . $term->term_id;
        }
    }

    // Classes de arquivo para CPT
    if ( is_post_type_archive() ) {
        $post_type = get_query_var( 'post_type' );
        if ( is_array( $post_type ) ) {
            $post_type = reset( $post_type );
        }
        $classes[] = 'archive-cpt-' . sanitize_html_class( $post_type );
    }

    return $classes;
}
add_filter( 'body_class', 'wppoland_add_cpt_taxonomy_body_class' );

Classes específicas do WooCommerce

Para lojas WooCommerce, existem várias páginas específicas que requerem estilos diferentes. Aqui está uma função estendida para classes específicas do WooCommerce:

/**
 * Adiciona classes específicas do WooCommerce
 *
 * @param array $classes Classes existentes do body
 * @return array Classes modificadas
 */
function wppoland_add_woocommerce_body_class( $classes ) {
    if ( ! function_exists( 'is_woocommerce' ) ) {
        return $classes;
    }

    // WooCommerce ativado
    $classes[] = 'woocommerce-active';

    // Páginas de loja
    if ( is_shop() ) {
        $classes[] = 'woocommerce-shop';

        // Categoria de produto
        $product_cat = get_queried_object();
        if ( $product_cat && ! is_wp_error( $product_cat ) ) {
            $classes[] = 'product-category-' . sanitize_html_class( $product_cat->slug );
        }
    }

    // Páginas de produto
    if ( is_product() ) {
        $classes[] = 'single-product';

        // Categorias do produto atual
        $product_cats = get_the_terms( get_the_ID(), 'product_cat' );
        if ( $product_cats && ! is_wp_error( $product_cats ) ) {
            foreach ( $product_cats as $cat ) {
                $classes[] = 'has-product-cat-' . sanitize_html_class( $cat->slug );
            }
        }
    }

    // Carrinho
    if ( is_cart() ) {
        $classes[] = 'woocommerce-cart';

        // Detectar carrinho vazio
        if ( WC()->cart->is_empty() ) {
            $classes[] = 'cart-empty';
        } else {
            $classes[] = 'cart-filled';
        }
    }

    // Checkout
    if ( is_checkout() ) {
        $classes[] = 'woocommerce-checkout';

        // Página de pagamento
        if ( is_wc_endpoint_url( 'order-pay' ) ) {
            $classes[] = 'order-payment';
        }
    }

    // Conta do usuário
    if ( is_account_page() ) {
        $classes[] = 'woocommerce-account';

        // Páginas específicas de conta
        if ( is_wc_endpoint_url( 'orders' ) ) {
            $classes[] = 'my-orders';
        } elseif ( is_wc_endpoint_url( 'downloads' ) ) {
            $classes[] = 'my-downloads';
        } elseif ( is_wc_endpoint_url( 'edit-address' ) ) {
            $classes[] = 'edit-address';
        } elseif ( is_wc_endpoint_url( 'payment-methods' ) ) {
            $classes[] = 'payment-methods';
        }
    }

    return $classes;
}
add_filter( 'body_class', 'wppoland_add_woocommerce_body_class', 20 );

Exemplo de estilização WooCommerce:

/* Headers específicos por categoria de produto */
body.product-category-eletronica .product-header {
    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
    color: white;
}

body.product-category-roupas .product-header {
    background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
    color: #333;
}

/* Call-to-action para carrinho vazio */
body.woocommerce-cart.cart-empty .cart-empty-content {
    text-align: center;
    padding: 60px 20px;
}

body.woocommerce-cart.cart-empty .return-to-shop {
    margin-top: 30px;
}

body.woocommerce-cart.cart-empty .button {
    background: #667eea;
    color: white;
    padding: 15px 30px;
    border-radius: 8px;
    font-size: 18px;
}

Considerações de desempenho e otimização

Cache de classes do body

Em temas complexos com muitos filtros de classes body, o desempenho pode sofrer. Aqui está uma versão otimizada que usa cache:

/**
 * Versão otimizada com transients para melhor performance
 *
 * @param array $classes Classes existentes do body
 * @return array Classes modificadas
 */
function wppoland_optimized_slug_body_class( $classes ) {
    global $post;

    if ( ! isset( $post ) || ! is_singular() ) {
        return $classes;
    }

    // Chave de cache baseada no ID do post
    $cache_key = 'wppoland_body_classes_' . $post->ID;
    $cached_classes = get_transient( $cache_key );

    // Se estiver em cache, usar valores em cache
    if ( false !== $cached_classes && is_array( $cached_classes ) ) {
        return array_merge( $classes, $cached_classes );
    }

    $additional_classes = array();

    // Slug da página atual
    $additional_classes[] = 'page-slug-' . sanitize_html_class( $post->post_name );

    // Pais e ancestrais
    $ancestors = get_post_ancestors( $post->ID );
    foreach ( $ancestors as $ancestor_id ) {
        $ancestor = get_post( $ancestor_id );
        if ( $ancestor ) {
            $additional_classes[] = 'ancestor-' . sanitize_html_class( $ancestor->post_name );
        }
    }

    // Slug do pai direto
    if ( $post->post_parent ) {
        $parent = get_post( $post->post_parent );
        if ( $parent ) {
            $additional_classes[] = 'parent-' . sanitize_html_class( $parent->post_name );
        }
    }

    // Armazenar em cache (1 hora)
    set_transient( $cache_key, $additional_classes, HOUR_IN_SECONDS );

    return array_merge( $classes, $additional_classes );
}
add_filter( 'body_class', 'wppoland_optimized_slug_body_class' );

Limpar cache quando posts são atualizados

Para garantir que as classes atualizadas sejam refletidas, limpe os transients quando um post for modificado:

/**
 * Limpa o cache de classes body quando posts são atualizados
 *
 * @param int $post_id ID do post sendo limpo
 */
function wppoland_clear_body_class_cache( $post_id ) {
    // Ignorar auto-saves e revisões
    if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
        return;
    }

    // Limpar cache para este post e seus descendentes
    delete_transient( 'wppoland_body_classes_' . $post_id );

    // Limpar cache para posts ancestrais
    $ancestors = get_post_ancestors( $post_id );
    foreach ( $ancestors as $ancestor_id ) {
        delete_transient( 'wppoland_body_classes_' . $ancestor_id );
    }

    // Limpar cache para posts descendentes
    $descendants = get_posts( array(
        'post_type' => 'page',
        'post_parent' => $post_id,
        'fields' => 'ids',
        'posts_per_page' => -1,
    ) );
    foreach ( $descendants as $descendant_id ) {
        delete_transient( 'wppoland_body_classes_' . $descendant_id );
    }
}
add_action( 'save_post', 'wppoland_clear_body_class_cache' );

Dicas de implementação

Combinando todos os filtros

Para máxima flexibilidade, combine todos os filtros em um único MU-plugin ou no functions.php do tema:

/**
 * Combina todos os filtros de classes body em um único arquivo
 */

// Slug e hierarquia de páginas
add_filter( 'body_class', 'wppoland_add_slug_body_class' );

// Funções de usuário
add_filter( 'body_class', 'wppoland_add_user_role_body_class' );

// CPT e Taxonomias
add_filter( 'body_class', 'wppoland_add_cpt_taxonomy_body_class' );

// WooCommerce (se ativo)
if ( function_exists( 'is_woocommerce' ) ) {
    add_filter( 'body_class', 'wppoland_add_woocommerce_body_class', 20 );
}

Usando com temas de bloco (Full Site Editing)

Para temas de bloco WordPress, adicione ao functions.php do tema ou a um plugin de funcionalidades:

/**
 * Suporte a classes body para temas de bloco
 *
 * @param array $classes Classes existentes
 * @return array Classes modificadas
 */
function wppoland_block_theme_body_classes( $classes ) {
    global $wp_query;

    // Detectar se é um tema de bloco
    if ( ! function_exists( 'wp_is_block_theme' ) || ! wp_is_block_theme() ) {
        return $classes;
    }

    // Adicionar classes específicas de template
    if ( is_singular() ) {
        $template_type = get_template_part_type();
        if ( $template_type ) {
            $classes[] = 'template-' . sanitize_html_class( $template_type );
        }
    }

    return $classes;
}
add_filter( 'body_class', 'wppoland_block_theme_body_classes', 10, 1 );

Solução de problemas

Classes não aparecem

Se as classes não estiverem aparecendo:

  1. Verifique se o filtro está conectado: Certifique-se de que add_filter está sendo executado
  2. Verifique se é uma página: O snippet só funciona em páginas (is_page())
  3. Verifique permissões de usuário: Algumas classes podem requerer privilégios de administrador
  4. Limpe caches: Cache de tema ou servidor pode estar retendo classes antigas

Conflitos com temas

Se houver conflitos com o tema:

  1. Prioridade do filtro: Tente alterar a prioridade do filtro

    add_filter( 'body_class', 'wppoland_add_slug_body_class', 20 );
  2. Verificar tema pai: O filtro pode precisar ser adicionado ao tema pai, não ao filho

  3. Override de classes: O tema pode estar substituindo classes completamente

Debug de classes

Para ver todas as classes sendo adicionadas:

/**
 * Debug: Mostrar todas as classes do body
 */
function wppoland_debug_body_classes( $classes ) {
    if ( current_user_can( 'administrator' ) ) {
        error_log( 'Body classes: ' . print_r( $classes, true ) );
    }
    return $classes;
}
add_filter( 'body_class', 'wppoland_debug_body_classes', 999 );

Melhores práticas

  1. Use nomes semânticos: Prefira parent-services a parent-123
  2. Limite o número de classes: Não adicione mais de 10-15 classes extras
  3. Use cache para sites grandes: Transients melhoram performance significativamente
  4. Documente suas classes: Mantenha um registro das classes personalizadas
  5. Teste em dispositivos móveis: Algumas classes podem afetar layouts responsivos
  6. Versione seu código: Use controle de versão para rastrear mudanças

Resumo

Adicionar slugs da página pai às classes do body é uma técnica simples mas poderosa que torna o targeting CSS escalável e sustentável. Em vez de manter listas de IDs de página, você pode direcionar seções inteiras com uma única classe.

Benefícios:

  • ✅ Escalável: Funciona automaticamente para novas páginas
  • ✅ Sustentável: Uma regra CSS para seções inteiras
  • ✅ Semântico: Nomes de classe legíveis
  • ✅ Flexível: Funciona com qualquer tema
  • ✅ Performance: Suporte a cache para sites grandes
  • ✅ Extensível: Adicione classes para CPTs, taxonomias, WooCommerce e muito mais

Atualizado: 29 de janeiro de 2026

O que é Adicionar slug da página pai às classes do body (snippet WordPress)?
Adicionar slug da página pai às classes do body (snippet WordPress) é um aspeto essencial da gestão de sites WordPress que ajuda a melhorar o desempenho, a segurança e a experiência do utilizador.
Como funciona o Adicionar slug da página pai às classes do body (snippet WordPress)?
Adicionar slug da página pai às classes do body (snippet WordPress) envolve a configuração de várias definições e a implementação das melhores práticas para otimizar o seu site WordPress.
Porque é que o Adicionar slug da página pai às classes do body (snippet WordPress) é importante para o WordPress?
Adicionar slug da página pai às classes do body (snippet WordPress) é crucial porque tem um impacto direto nos rankings do seu site nos motores de busca, na velocidade de carregamento e no sucesso geral.

Precisa de FAQ adaptado ao setor e mercado? Criamos uma versão alinhada com os seus objetivos de negócio.

Fale connosco

Artigos Relacionados