In a multisite, how can I get posts from one site and display their permalinks in another site?

I have a WordPress multisite with one main site and four sub-sites. In a PHP template on my main site, I would like to get the posts from one of the sub-sites and print the permalinks to the page. How is this done?

My code is below--when this code is executed, permalinks are indeed printed to the screen, but they are incorrect--the post name is correct, but the path is incorrect.

$tp_blog_id = 4;
switch_to_blog( $tp_blog_id );
$posts = get_posts(
            array(
                'post_type' = 'property',
                'posts_per_page' = 100,
                'numberposts' = -1
            )
);
restore_current_blog();
error_log(print_r($posts,true));
foreach ($posts as $post) {
    echo "The URL is: br";    
    echo get_blog_permalink( $tp_blog_id, $post-ID ) . "br";
}

Here is a screenshot of the output page. The permalinks incorrect--each of those leads to a 404 page. The incorrect permalinks printed in this case are of the form

http://dev.thailandproperty-hh.com/pattaya/blog/property/1-bedroom-condo-central-pattaya-10/

when in actuality the permalinks are

http://dev.thailandproperty-hh.com/pattaya/property/1-bedroom-condo-central-pattaya-10/.

As a test, to my error log, I printed the contents of the $posts array. It does indeed contain all the desired post objects. In addition, each post object in the array has a property guid, the value of which is the correct permalink (screenshot). I guess as a workaround I could simply echo this property to the page, instead of get_blog_permalink(). But I'd like to understand why the latter is not returning the expected permalink.

UPDATE

I register my CPT using code below:

$slug = get_theme_mod( 'property_permalink' );
$slug = ( empty( $slug ) ) ? 'property' : $slug;
    $args = array(
        'labels'              = $labels,
        'public'              = true,
        'publicly_queryable'  = true,
        'show_ui'             = true,
        'show_in_menu'        = true,
        'query_var'           = true,
        'rewrite'             = array( 'slug' = $slug ),
        'capability_type'     = 'post',
        'has_archive'         = true,
        'hierarchical'        = false,
        'menu_position'       = null,
        'supports'            = $supports,
        'taxonomies'          = array( 'property_type' )
    );

register_post_type( 'property', $args );

Topic get-posts permalinks multisite Wordpress

Category Web


Let's take a look at get_blog_permalink:

get_blog_permalink( $blog_id, $post_id ) {
    switch_to_blog( $blog_id );
    $link = get_permalink( $post_id );
    restore_current_blog();

    return $link;
}

As you can see, there's no magic... But there are some problems, since switch_to_blog isn't very efficient...

It means that it would be way better if you'd done it this way:

$tp_blog_id = 4;
switch_to_blog( $tp_blog_id );
$posts = get_posts(
            array(
                'post_type' => 'property',
                'posts_per_page' => 100,
                'numberposts' => -1
            )
);

error_log( print_r($posts,true) );
foreach ( $posts as $post ) {
    echo "The URL is: <br>";    
    echo get_permalink( $post->ID ) . "<br>";
}
restore_current_blog();

And if the problem with permalinks still occur, then you'll have to check the way you register this CPT (especially the with_front part of rewrite param in register_post_type).

And as I expected, the problem lies exactly in that spot. When you register your CPT you use:

'rewrite' => array( 'slug' => $slug ),

If you'll take a look at register_post_type docs, then you'll see that this param has multiple fields:

  • slug => string Customize the permalink structure slug. Defaults to the $post_type value. Should be translatable.
  • with_front => bool Should the permalink structure be prepended with the front base. (example: if your permalink structure is /blog/, then your links will be: false->/news/, true->/blog/news/). Defaults to true
  • feeds => bool Should a feed permalink structure be built for this post type. Defaults to has_archive value.
  • pages => bool Should the permalink structure provide for pagination. Defaults to true
  • ep_mask => const As of 3.4 Assign an endpoint mask for this post type. For more info see Rewrite API/add_rewrite_endpoint, and Make WordPress Plugins summary of endpoints. If not specified, then it inherits from permalink_epmask(if permalink_epmask is set), otherwise defaults to EP_PERMALINK.

As you can see one of them is with_front and its default value is true. That means that your post type is told to prepend front base to its URLs.

So if the front base is set to blog, then the URL for that post type shuld contain it - so it's generated correctly...

PS. It's hard to say why it causes 404 errors and how exactly are these links processed, so it works without front base. But your problem is clear - there is something wrong with registering and processing that CPT.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.