This snippet for WordPress Multisite is meant to be utilized for a network of sites sharing content between each other, but linking back to the original site in order to keep the content owner as the owner of the post being displayed.
This is how it would look in regular use in a pattern used on a news site:

Here’s how the shortcode would look in use in the same above pattern example:

The Network Posts snippet is meant to be a replacement for using an RSS reader for a multisite network for content delivery, but only for regular WordPress posts within a multisite network.
Here’s how it would be used in a typical situation with the shortcode block, whether on a post, page, or within a pre-built block or pattern:
[network_posts site_id="2" category_slug="news" posts_per_page="3" show_featured_image="true" image_size="thumbnail" title_position="below"]
The Network Posts snippet can be used as a simple php plugin file (saved in the plugins folder of the main site on your multisite network) or added with the Code Snippets plugin. (Editorial note: I utilized this solution with the Code Snippets plugin and registered it across the network, but it should have the ability to add the snippet site by site.)
Here’s the code, made available under the GPL license for anyone to use:
/**
* Shortcode to display posts from another site in a WordPress Multisite network with styling options.
*
* Usage:
* [network_posts site_id="2" category_slug="news" posts_per_page="3" show_featured_image="true" image_size="thumbnail" title_position="below"]
*
* Attributes:
* - site_id (required): The ID of the site to pull posts from.
* - category_slug (optional): The slug of the category to filter posts by.
* - posts_per_page (optional): Number of posts to display (default: 5).
* - post_type (optional): The post type to query (default: 'post').
* - show_featured_image (optional): 'true' or 'false' (default: 'false'). Set to 'true' to show.
* - image_size (optional): WordPress image size slug (e.g., 'thumbnail', 'medium', 'large', 'full'). Default 'thumbnail'.
* - title_position (optional): 'above' or 'below' (default: 'above'). Position of the title relative to the image.
*/
function display_network_posts_shortcode( $atts ) {
// 1. Parse shortcode attributes
$atts = shortcode_atts(
array(
'site_id' => 0, // Site ID is required
'category_slug' => '',
'posts_per_page' => 5,
'post_type' => 'post',
'show_featured_image' => 'false', // Default to not showing image
'image_size' => 'thumbnail', // Default image size
'title_position' => 'above', // Default title position
),
$atts,
'network_posts'
);
$site_id = (int) $atts['site_id'];
$category_slug = sanitize_text_field( $atts['category_slug'] );
$posts_per_page = (int) $atts['posts_per_page'];
$post_type = sanitize_text_field( $atts['post_type'] );
$show_featured_image = filter_var( $atts['show_featured_image'], FILTER_VALIDATE_BOOLEAN );
$image_size = sanitize_text_field( $atts['image_size'] );
$title_position = sanitize_text_field( $atts['title_position'] );
// Validate site_id
if ( $site_id <= 0 ) {
return '<p style="color: red;">Error: "site_id" attribute is required for [network_posts] shortcode.</p>';
}
// Initialize output buffer
ob_start();
// 2. Switch to the target blog context
switch_to_blog( $site_id );
// 3. Prepare WP_Query arguments
$args = array(
'post_type' => $post_type,
'posts_per_page' => $posts_per_page,
'post_status' => 'publish',
'no_found_rows' => true,
'meta_query' => $show_featured_image ? array(
array(
'key' => '_thumbnail_id',
'compare' => 'EXISTS',
),
) : array(),
);
if ( ! empty( $category_slug ) ) {
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $category_slug,
),
);
}
// 4. Run the query
$query = new WP_Query( $args );
// 5. Output the results
if ( $query->have_posts() ) {
echo '<div class="network-posts-list" style="list-style-type: none; padding-left: 0;">';
while ( $query->have_posts() ) {
$query->the_post();
echo '<li style="margin-bottom: 15px; display: block;">'; // Adjust spacing between items
if ( $show_featured_image && has_post_thumbnail() ) {
echo '<div style="display: block; margin-bottom: 5px;">'; // Container for image
echo '<a href="' . esc_url( get_permalink() ) . '" class="network-post-thumbnail-link" style="display: block;">';
the_post_thumbnail( $image_size, array( 'class' => 'network-post-thumbnail', 'style' => 'display: block; width: 100%; height: auto;' ) ); // Make image responsive within its container
echo '</a>';
echo '</div>';
}
echo '<h5 style="margin-top: 0;">';
echo '<a href="' . esc_url( get_permalink() ) . '" class="network-post-title" style="text-decoration: none;">' . esc_html( get_the_title() ) . '</a>';
echo '</h5>';
// You can add more post information here, e.g., the_excerpt(), the_date()
echo '</li>';
}
echo '</div>';
} else {
// Optional: return nothing if no posts are found to keep the page clean
}
// 6. Restore the context back to the original blog
restore_current_blog();
// 7. Reset post data to prevent conflicts with the main loop
wp_reset_postdata();
return ob_get_clean(); // Return the buffered content
}
// 8. Register the shortcode
add_shortcode( 'network_posts', 'display_network_posts_shortcode' );
Note the code was created with AI, but I believe it was a combination of systems that ultimately created the final product. (ChatGPT, Claude and Gemini were utilized during development.)
Please feel free to edit the plugin for your own use, but if you don’t mind please shoot an email to info@myrickmultimedia.com if you create improvements you’d like to share. I’d be happy to host them.














Leave a Reply
You must be logged in to post a comment.