0

I've created a multisite on a local VM and installed my theme.

Now I'm trying to get the latest posts from all the sites in order to display them ordered by last updated on homepage.

From what I've read so far, the best option should be creating a custom template for my home page. Is it correct? So I take the code in my template page.php but I cannot understand how to change it.

    <?php
    /**
     * The template for displaying all pages.
     *
     * This is the template that displays all pages by default.
     * Please note that this is the WordPress construct of pages and that other
     * 'pages' on your WordPress site will use a different template.
     *
     */

    get_header();

    global $heap_private_post;

    if ( post_password_required() && ! $heap_private_post['allowed'] ) {
        // password protection
        get_template_part( 'theme-partials/password-request-form' );

    } else { ?>
        <div class="page-content single-page-content">

            <?php if ( have_posts() ): the_post(); ?>

                <article class="article page page-single page-regular">
                    <header>
                        <?php if ( has_post_thumbnail() ):
                            $image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full-size' );
                            if ( ! empty( $image[0] ) ): ?>
                                <div class="page__featured-image">
                                    <img src="<?php echo $image[0] ?>" alt="<?php the_title(); ?>"/>
                                </div>
                            <?php endif;
                        endif; ?>
                    </header>
                    <div class="page__wrapper">
                        <section class="page__content  js-post-gallery  cf">
                            <h1 class="page__title"><?php the_title(); ?></h1>
                            <hr class="separator separator--dark"/>
                            <?php the_content(); ?>

                        </section>
                        <?php
                        global $numpages;
                        if ( $numpages > 1 ):
                            ?>
                            <div class="entry__meta-box  meta-box--pagination">
                                <span class="meta-box__title"><?php _e( 'Pages', 'heap' ) ?></span>
                                <?php
                                $args = array(
                                    'before'           => '<ol class="nav  pagination--single">',
                                    'after'            => '</ol>',
                                    'next_or_number'   => 'next_and_number',
                                    'previouspagelink' => __( '&laquo;', 'heap' ),
                                    'nextpagelink'     => __( '&raquo;', 'heap' )
                                );
                                wp_link_pages( $args );
                                ?>
                            </div>
                            <?php
                        endif;

                        //comments
                        if ( comments_open() || '0' != get_comments_number() ):
                            comments_template();
                        endif; ?>
                    </div>
                </article>

                <?php
            else :
                get_template_part( 'no-results' );
            endif; ?>

        </div><!-- .page-content -->

    <?php } // close if password protection

    get_footer();

EDIT I was able to achieve it using this code:

foreach( $subsites as $subsite ) {
    $subsite_id = get_object_vars($subsite)["blog_id"];
    $subsite_name = get_blog_details($subsite_id)->blogname;
    switch_to_blog($subsite_id);
    $blog_posts = get_posts(); 
    restore_current_blog();
    foreach( $blog_posts as $post ) {
        setup_postdata( $post );
    }
  • There is not an easy way to get posts from all subsites. Each query or loop you do will only pull from a single site. So, you would have to get a list of all subsites, query each, and then merge all of the arrays and order by date. That would be a massive operation, so you may want to rethink the site architecture and use a single site with custom post types instead. That way you can still restrict people to editing a certain section (one or two post types) but only have 1 site to query. – WebElaine Mar 24 at 15:36
  • Thanks @WebElaine, I will give a try following your suggestion. Looking around I found out something like this: $all_blog = wp_get_sites(); foreach ($blog_ids as $key=>$current_blog) { // switch to each blog to get the posts switch_to_blog($current_blog['blog_id']); // fetch all the posts $blog_posts = get_posts(array( 'posts_per_page' => -1)); restore_current_blog(); // display all posts } Is it correct? How should I use it on template? – CrazYoshi Mar 24 at 15:59
  • @CrazYoshi what you want to do is very very expensive/slow, and also has caveats. For example, custom post types won't work unless the same post type is defined on the site that's running the code – Tom J Nowell Mar 24 at 16:29
  • Thanks @TomJNowell. What I would like to achive is having "mysite.com" and different categories (A,B,C). When the user from homepage navigate to A, i would like to go to "A.mysite.com". In the homepage i would like to show all articles from all categories, while in A.mysite.com i would like to show only the one belongs to A. How do you suggest to proceed? – CrazYoshi Mar 24 at 17:18
0

There is actually a way to get posts from all multisite sub-sites. I do it with my "Multisite Media Display" plugin here https://wordpress.org/plugins/multisite-media-display/ .

I use it to display all media items from my multisite to ensure that any submissions meet the site requirements. Works great.

I have a similar plugin for posts, but it doesn't work with the current WP version. Been a low priority to update it.

But you can get an array of all sub-sites (although the function that does that doesn't work with WP versions prior to 4.6). Then you loop through that array, doing a post query as needed.

ADDED

Here's some code, with comments. The code will get all subsites, then switch to each subsite, where you can put in your query and output the posts in 'the loop'.

$subsites_object = get_sites(); // get the sites into an object
// convert to an array
$subsites = objectToArray($subsites_object);
// process each subsite
foreach ($subsites as $subsite) {
// get some values for later if needed
    // $subsite_id is important; that switches to the subsite
    $subsite_id     = $subsite["blog_id"];
    $subsite_name   = get_blog_details($subsite_id)->blogname;
    $subsite_path   = $subsite["path"];
    $subsite_domain = $subsite["domain"];
    switch_to_blog($subsite_id);
// do your post query, then do 'the loop' to get posts
}

You could put that into a template. Or you could add code for a shortcode that will output things.

Lots of help on the googles/bings/ducks. Look at the WP code docs to find out what each thing does.

| improve this answer | |
  • How should I get all the sub-sites and loop on the result array to get the post? I'm pretty new to wordpress and I'm not able to change the template in the correct way – CrazYoshi Mar 24 at 22:59
  • See added code in the answer. Just to get you started. – Rick Hellewell Mar 25 at 0:20
  • Thanks, it works correctly but I still have one question. How could I get the latest post and apply an order by CreationDate on all of them? Can I save them in an array, sort them and then use a get_template_part for each of them? – CrazYoshi May 4 at 15:35
  • You need to add your desired code in The Loop - which you place after the switch_to_blog line. That's where you put your query, and then display the results via The Loop. Look in the WP Developer docs for sample "The Loop' code. – Rick Hellewell May 4 at 16:12
  • I already had all the post using a loop, how to combine all the post retrived inside each loop together in order to order all of them by creation date. This is my loop: $subsites = get_sites(); foreach( $subsites as $subsite ) { $subsite_id = get_object_vars($subsite)["blog_id"]; switch_to_blog($subsite_id); $query = new WP_Query( array( 'posts_per_page' => 5 ) ); if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); get_template_part('test'); } restore_current_blog(); } – CrazYoshi May 4 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.