Aula: Sitemap para uso do MU ‘Admin Menu Editor’ e ocultar categorias vazias
Melhoria implementada: No sitemap unificado, categorias e subcategorias que não contêm nenhum post (do tipo correspondente: post normal ou aula) agora são automaticamente ocultadas, deixando o índice muito mais limpo e profissional.
Na função neodoor_render_taxonomy_section, iteramos sobre as subcategorias e, para cada uma, contamos quantos posts do tipo atual existem. Se zero, pulamos a subcategoria. Se após esse filtro uma categoria pai ficar sem nenhuma subcategoria, a categoria pai também é ocultada.
Abaixo está o código completo do MU-Plugin neodoor-sitemaps-unified.php com a melhoria incluída. Substitua o arquivo existente por este.
<?php
/**
* Plugin Name: Neodoor Sitemaps Unified
* Description: Sitemaps HTML: [sitemap_wp] (posts), [sitemap_lessons] (aulas), [sitemap_completo] (ambos). Oculta categorias sem posts.
* Version: 2.1
* Author: Reinaldo (Neodoor.neo)
*/
defined( 'ABSPATH' ) || exit;
add_shortcode( 'sitemap_wp', 'neodoor_sitemap_wp_shortcode' );
add_shortcode( 'sitemap_lessons', 'neodoor_sitemap_lessons_shortcode' );
add_shortcode( 'sitemap_completo', 'neodoor_sitemap_full_shortcode' );
function neodoor_sitemap_wp_shortcode() {
return neodoor_sitemap_render( 'post', 'Blog' );
}
function neodoor_sitemap_lessons_shortcode() {
return neodoor_sitemap_render( 'neodoor_aula', 'Caderno de Estudos' );
}
function neodoor_sitemap_full_shortcode() {
$html = '<div class="neodoor-sitemap-wrapper">';
$html .= neodoor_sitemap_render( 'post', 'Blog' );
$html .= neodoor_sitemap_render( 'neodoor_aula', 'Caderno de Estudos' );
$html .= '</div>';
return $html;
}
function neodoor_sitemap_render( $post_type, $title ) {
ob_start();
?>
<div class="sitemap-section">
<h2><?php echo esc_html( $title ); ?></h2>
<?php echo neodoor_render_taxonomy_section( 'category', $post_type ); ?>
</div>
<?php
return ob_get_clean();
}
/**
* Renderiza categorias e subcategorias, ocultando aquelas sem posts do tipo atual.
*/
function neodoor_render_taxonomy_section( $taxonomy = 'category', $post_type = 'post' ) {
$categorias_pai = get_terms( array(
'taxonomy' => $taxonomy,
'parent' => 0,
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
) );
if ( empty( $categorias_pai ) || is_wp_error( $categorias_pai ) ) {
return '<p>Nenhuma categoria encontrada para este tipo de conteúdo.</p>';
}
$html = '';
foreach ( $categorias_pai as $pai ) {
if ( $pai->term_id == 11 ) continue; // opcional
$subcategorias = get_terms( array(
'taxonomy' => $taxonomy,
'parent' => $pai->term_id,
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
) );
if ( empty( $subcategorias ) || is_wp_error( $subcategorias ) ) {
continue;
}
$has_any = false;
$subcat_html = '';
foreach ( $subcategorias as $subcat ) {
$total = neodoor_count_posts_in_term( $post_type, $subcat->term_id );
if ( $total == 0 ) continue;
$has_any = true;
$posts_iniciais = get_posts( array(
'post_type' => $post_type,
'tax_query' => array( array(
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $subcat->term_id,
) ),
'post_status' => 'publish',
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC',
) );
$subcat_html .= '<div class="sitemap-subcategoria">';
$subcat_html .= '<h5>' . esc_html( $subcat->name ) . '</h5>';
$subcat_html .= '<ul class="sitemap-posts-list" id="sitemap-list-' . $post_type . '-' . $subcat->term_id . '">';
foreach ( $posts_iniciais as $post ) {
$subcat_html .= sprintf( '<li><a href="%s">%s</a> (%s)</li>',
esc_url( get_permalink( $post ) ),
esc_html( $post->post_title ),
get_the_date( 'd/m/Y', $post )
);
}
$subcat_html .= '</ul>';
if ( $total > 5 ) {
$subcat_html .= '<button class="sitemap-load-more"
data-term_id="' . esc_attr( $subcat->term_id ) . '"
data-post_type="' . esc_attr( $post_type ) . '"
data-offset="5"
data-total="' . esc_attr( $total ) . '"
data-per_page="5">Carregar mais</button>';
$subcat_html .= '<span class="sitemap-loading" style="display:none;">Carregando...</span>';
}
$subcat_html .= '</div>';
}
if ( $has_any ) {
$html .= '<div class="sitemap-categoria"><h4>' . esc_html( $pai->name ) . '</h4>' . $subcat_html . '</div>';
}
}
return $html;
}
function neodoor_count_posts_in_term( $post_type, $term_id ) {
$query = new WP_Query( array(
'post_type' => $post_type,
'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $term_id,
) ),
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
) );
$count = $query->post_count;
wp_reset_postdata();
return $count;
}
add_action( 'wp_ajax_neodoor_sitemap_load_more', 'neodoor_sitemap_ajax_handler' );
add_action( 'wp_ajax_nopriv_neodoor_sitemap_load_more', 'neodoor_sitemap_ajax_handler' );
function neodoor_sitemap_ajax_handler() {
$term_id = intval( $_POST['term_id'] );
$offset = intval( $_POST['offset'] );
$per_page = intval( $_POST['posts_per_page'] );
$post_type = sanitize_key( $_POST['post_type'] );
if ( ! $term_id ) wp_send_json_error( 'Termo inválido' );
$posts = get_posts( array(
'post_type' => $post_type,
'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $term_id,
) ),
'post_status' => 'publish',
'posts_per_page' => $per_page,
'offset' => $offset,
'orderby' => 'date',
'order' => 'DESC',
) );
$html = '';
$count = 0;
foreach ( $posts as $post ) {
$html .= sprintf( '<li><a href="%s">%s</a> (%s)</li>',
esc_url( get_permalink( $post ) ),
esc_html( $post->post_title ),
get_the_date( 'd/m/Y', $post )
);
$count++;
}
wp_send_json_success( array( 'html' => $html, 'count' => $count ) );
}
Como testar
- Crie uma categoria “Teste” sem nenhum post associado a ela.
- Visualize a página que usa
[sitemap_wp]– a categoria não aparecerá. - Adicione um post do tipo correto a essa categoria e recarregue – agora ela aparece.
Registro no caderno: data – melhoria de usabilidade no sitemap, ocultando automaticamente seções vazias.