Trying to share a Custom Post from main site to a child site on a multisite network. I am 80% there, with the use of switch_blog I am able to query custom posts on my templates on the child site. I DO NOT want to be duplicating posts for this purpose within the newtwork, I am happy for them all to be sitting and edited on master, whereas the child sites will just read the data. I want to have the same urls, with same content (canonical of course) on both master and sister sites for these custom posts.

One thing remains for this, the single post template - single-items.php This works fine on the main site where it uses some heavy rewrites to display the single custom post on a url of the type: /something/taxonomy1/taxonomy2/taxonomy3/single-post

However, on the child site, as there is no single items in the list (they are all on master) it displays a 404.

Is there a way to hook into the single-post.php template loading so as to force the switch_blog before wordpress goes to check whether the single custom post in question exists and throws a 404?

The part declaring the custom post is sitting in a plugin which is network activated (I thought this would have given me the same custom post on the child site with shared data from master, however when the child site was deployed the custom posts stayed empty).


1 Answer 1


I seem to have solved it with the following code which I cobbled together from other answers after searching last 24hrs.

It gave an error until I removed the restore_current_blog at the end of the function. As this should only be used by the singular page for the custom post type, I am hoping, it seems to work ok now. I am able to read and display single-CPT on the child site pulling in complete data. So a CPT living on master: master.com/tax1/tax2/yax3/single-CPT also works on slave: slave.com/tax1/tax2/yax3/single-CPT even though it is not there.

add_action('pre_get_posts', 'custom__pre_get_posts');
function custom__pre_get_posts($query){
    //Get access to global variables
    global $blog_id;
    global $wp_query;

    //Make sure we're not in admin, only run on the main query and don't run on our primary site
    if($query->is_admin || !$query->is_main_query() || $blog_id===1){

    //Try running the query
    //$test_obj = $query->get_queried_object();

    //If we didn't get a result then the page wasn't found
    if(in_array($query->get('post_type'), ['###MY-CUSTOM-POST###'])) {
      //Switch to the main site
      //Reset the query using the same args as the original (the previous reset changes $wpdb)
      //$wp_query = new WP_Query($query->query_vars);
      //Re-query the object again. We might need to perform more sanity checks here
      //$test_obj = $query->get_queried_object();
      //Switch back to our current site
      //This is a normal query for a page that exists, we don't need to do anything
  • noticed I can just keep switch_to_blog in there and could comment out everything else, after testing that seems to be all that is necessary
    – sash
    Mar 2, 2023 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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