0

I have a multisite network with some shared custom post types, and I'm trying to create a function that loads a custom single-{cpt} template for a given post type by $blog_id when defined, and otherwise fall-back to the default single- template. In this case, the custom post type is resource, which would default to single-resource.php and I'm setting a variable $custom_resource_single to the applicable template file name as follows:

if ($blog_id == 5) {
   $custom_resource_single = 'single-resource-alt.php';
}

I'm then trying to pass this variable to a function used as a callback in the template_include filter hook as follows (adapting somewhat from this thread), but it's not working:

function custom_resource_single($custom_resource_single, $template) {
    if ( is_singular('resource') && !empty($custom_resource_single) ) {
        $custom = locate_template($custom_resource_single);
        return $custom;
    }
    return $template;
}
add_filter( 'template_include', function() use ($custom_resource_single, $template) { custom_resource_single($custom_resource_single, $template); });

I attempting to use a closure based on some other threads I've found here, but I'm clearly not using it properly. I can successfully achieve the result by passing an anonymous function with the $blog_id conditional directly to template_include hook, but I'd really like to be able to pass a variable ($custom_resource_single) to the function that is defined elsewhere.

Please let me know if my aim as described above is unclear, and thanks in advance for any assistance.

  • "defined elsewhere" - but in the same scope as the closure? If so, you might be looking at passing variables by reference: use ( &$custom_resource_single ) ? But why don't you run the conditional from within the template_include filter - e.g. if ( 5 == get_current_blog_id() ) $template = 'single-resource-alt.php'; ? – Sally CJ Mar 19 at 4:12
  • @SallyCJ I've created a lib file called multisite-functions.php in which I've set up a bunch of options grouped by $blod_id to try to keep everything organized, so my hope is to to set the $custom_resource_single variable by $blog_id and then pass that variable to the function I described above, if that makes sense- I could do what you're suggesting, but I'd like to keep the conditional out of the filter function itself. I've been able to do so for other things like enabling custom post types, taxonomies, etc. but can't get it working for the single- template – nickpish Mar 19 at 4:31
  • I've just posted an answer. I hope it helps you. – Sally CJ Mar 19 at 5:29
1

Actually, I noticed that your closure is not capturing/using the proper $template variable which is passed from the template_include filter hook:

// This hook is defined in wp-includes/template-loader.php
$template = apply_filters( 'template_include', $template )

The closure is also not returning the template..

So your closure should look like:

add_filter( 'template_include', function( $template ) use ( $custom_resource_single ) {
    return custom_resource_single( $custom_resource_single, $template );
} );

But you may want to pass the $custom_resource_single by reference (use ( &$custom_resource_single )) in case it gets changed after the above closure:

if ( $blog_id == 5 ) {
    $custom_resource_single = 'single-resource-alt.php';
}

add_filter( 'template_include', function( $template ) use ( &$custom_resource_single ) {
    return custom_resource_single( $custom_resource_single, $template );
} );

// $custom_resource_single is changed here.
if ( /* condition */ ) {
    $custom_resource_single = 'file.php';
}
  • Thank you- this is working great! Question just from a learning standpoint- you're saying I could pass the variable by reference in the event that I might want to change it later? (Whereas just using $custom_resource_single would not allow it to be changed later?) – nickpish Mar 19 at 15:09
  • 1
    You're very welcome. :) And yes to the first question in your comment. But regarding the second question, let me answer it like this: When you pass a variable by reference (instead of by value, which is the default behavior in PHP), you can "listen" to the variable when its value gets changed outside of the closure, and secondly, you can also change the value from within the closure. Try this simple example/demonstration and check also Passing by Reference on php.net. I hope that helps. :) – Sally CJ Mar 19 at 16:46
  • Interesting, ok- thanks much for the explanation; that makes sense. I'll check out those links you provided! – nickpish Mar 19 at 17:37
  • Sure, take your time! (PS: Sorry about the "in your comment".. that just sounds funny, lol..) – Sally CJ Mar 19 at 18:02

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.