📘 MU-Plugin: Sitemap de Rede Avançado (com categorias e “Carregar mais”) – Versão 2.1
Arquivo: /wp-content/mu-plugins/sitemap-rede.php
Shortcode : Atributos: rede_sitemap incluir e excluir (IDs dos blogs). Colocar entre chaves [ rede _ sitemap ] e sem espaços
- Título do blog (link para a home)
- Categorias com pelo menos um post
- Os 5 posts mais recentes de cada categoria
- Botão “Carregar mais” que, via AJAX, traz os próximos 5 posts da categoria sem recarregar a página.
Você pode filtrar quais blogs aparecem usando os atributos incluir ou excluir, ex: . rede_sitemap rede_sitemap incluir="2,4"
Arquivo: /wp-content/mu-plugins/sitemap-rede.php
<?php
/**
* Plugin Name: Sitemap de Rede – Versão 2.1 [ rede _ sitemap ] sem espaços
* Description: Exibe blogs, categorias e os 5 posts mais recentes de cada categoria, com botão "Carregar mais" via AJAX.
* Version: 2.1
* Author: Reinaldo (Neodoor.neo)
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class Sitemap_Rede {
public function __construct() {
add_shortcode( 'rede_sitemap', array( $this, 'exibir_sitemap' ) );
add_action( 'wp_ajax_carregar_mais_posts', array( $this, 'ajax_carregar_mais_posts' ) );
add_action( 'wp_ajax_nopriv_carregar_mais_posts', array( $this, 'ajax_carregar_mais_posts' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
public function enqueue_scripts() {
global $post;
if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'rede_sitemap' ) ) {
wp_enqueue_script( 'jquery' );
wp_add_inline_script(
'jquery',
'jQuery(document).ready(function($) {
$(document).on("click", ".sitemap-carregar-mais", function(e) {
e.preventDefault();
var botao = $(this);
var categoriaId = botao.data("categoria-id");
var blogId = botao.data("blog-id");
var offset = botao.data("offset");
var container = botao.siblings(".sitemap-lista-posts");
$.ajax({
url: "' . admin_url( 'admin-ajax.php' ) . '",
type: "POST",
data: {
action: "carregar_mais_posts",
blog_id: blogId,
category_id: categoriaId,
offset: offset
},
beforeSend: function() {
botao.text("Carregando...");
},
success: function(response) {
if (response.success) {
container.append(response.data.html);
botao.data("offset", offset + 5);
if (!response.data.has_more) {
botao.remove();
} else {
botao.text("Carregar mais");
}
} else {
alert("Erro ao carregar mais posts.");
botao.text("Tentar novamente");
}
},
error: function() {
alert("Erro na requisição.");
botao.text("Tentar novamente");
}
});
});
});'
);
}
}
public function ajax_carregar_mais_posts() {
$blog_id = intval( $_POST['blog_id'] );
$category_id = intval( $_POST['category_id'] );
$offset = intval( $_POST['offset'] );
$posts_per_page = 5;
switch_to_blog( $blog_id );
$args = array(
'cat' => $category_id,
'posts_per_page' => $posts_per_page,
'offset' => $offset,
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish',
);
$query = new WP_Query( $args );
$html = '';
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$html .= sprintf(
'<li><a href="%s">%s</a></li>',
esc_url( get_permalink() ),
esc_html( get_the_title() )
);
}
}
$has_more = ( $offset + $posts_per_page ) < $query->found_posts;
wp_reset_postdata();
restore_current_blog();
wp_send_json_success( array( 'html' => $html, 'has_more' => $has_more ) );
}
public function exibir_sitemap( $atts ) {
$atts = shortcode_atts(
array(
'incluir' => '',
'excluir' => '',
),
$atts,
'rede_sitemap'
);
$sites = get_sites( array( 'number' => 0, 'public' => 1 ) );
if ( empty( $sites ) ) {
return '<p>Nenhum site encontrado na rede.</p>';
}
$incluir_ids = ! empty( $atts['incluir'] ) ? array_map( 'intval', explode( ',', $atts['incluir'] ) ) : array();
$excluir_ids = ! empty( $atts['excluir'] ) ? array_map( 'intval', explode( ',', $atts['excluir'] ) ) : array();
$html = '<div class="sitemap-rede-v2">';
foreach ( $sites as $site ) {
$blog_id = $site->blog_id;
if ( ! empty( $incluir_ids ) && ! in_array( $blog_id, $incluir_ids ) ) continue;
if ( ! empty( $excluir_ids ) && in_array( $blog_id, $excluir_ids ) ) continue;
switch_to_blog( $blog_id );
$site_title = get_bloginfo( 'name' );
$site_url = home_url();
$html .= sprintf(
'<div class="sitemap-blog" data-blog-id="%d">
<h2><a href="%s">%s</a></h2>',
$blog_id,
esc_url( $site_url ),
esc_html( $site_title )
);
$categories = get_categories( array( 'hide_empty' => true ) );
if ( ! empty( $categories ) ) {
$html .= '<div class="sitemap-categorias">';
foreach ( $categories as $category ) {
$posts_inicial = get_posts( array(
'cat' => $category->term_id,
'posts_per_page' => 5,
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish',
) );
$html .= sprintf(
'<div class="sitemap-categoria" data-categoria-id="%d" data-blog-id="%d">
<h3>%s</h3>
<ul class="sitemap-lista-posts">',
$category->term_id,
$blog_id,
esc_html( $category->name )
);
foreach ( $posts_inicial as $post ) {
$html .= sprintf(
'<li><a href="%s">%s</a></li>',
esc_url( get_permalink( $post ) ),
esc_html( $post->post_title )
);
}
if ( $category->count > 5 ) {
$html .= sprintf(
'</ul><button class="sitemap-carregar-mais" data-blog-id="%d" data-categoria-id="%d" data-offset="5">Carregar mais</button>',
$blog_id,
$category->term_id
);
} else {
$html .= '</ul>';
}
$html .= '</div>';
}
$html .= '</div>';
} else {
$html .= '<p>Este blog ainda não possui categorias com posts.</p>';
}
$html .= '</div>';
restore_current_blog();
}
$html .= '</div>';
// CSS básico
$html .= '<style>
.sitemap-rede-v2{max-width:1200px;margin:0 auto;font-family:sans-serif}
.sitemap-blog{margin-bottom:3rem;border-bottom:1px solid #eee;padding-bottom:1.5rem}
.sitemap-blog h2{margin-bottom:1rem}
.sitemap-categorias{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1.5rem}
.sitemap-categoria{background:#f9f9f9;padding:1rem;border-radius:8px;box-shadow:0 1px 3px rgba(0,0,0,0.05)}
.sitemap-categoria h3{margin-top:0;margin-bottom:.75rem;font-size:1.2rem}
.sitemap-lista-posts{margin:0;padding-left:1.2rem;font-size:.9rem}
.sitemap-lista-posts li{margin-bottom:.3rem}
.sitemap-carregar-mais{background:#007cba;color:#fff;border:none;padding:5px 12px;border-radius:4px;cursor:pointer;font-size:.8rem;margin-top:.5rem;transition:background .2s}
.sitemap-carregar-mais:hover{background:#005a87}
</style>';
return $html;
}
}
new Sitemap_Rede();
?>
Instruções finais:
- No seu post, mude para o modo “Texto” (editor clássico).
- Apague todo o conteúdo existente.
- Cole este código HTML (ele já está completamente escapado, inclusive os shortcodes de exemplo).
- Atualize o post sem alternar para o modo “Visual”.