[MU] Sitemap para o admin-menu-editor

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.

✅ Voto computado! Obrigado.

Média: 3.1 (31 votos)