I guess my question is when are
is_singular() && in_the_loop()both true?
Note that both is_singular() and in_the_loop() point to the main WordPress query set via wp() (see Query Overview on WordPress Codex) which uses the global $wp_query variable.
Secondly, we create/start a loop when we call have_posts() and the_post(), and only after that would in_the_loop() return a true. Example:
// For the main query.
if ( have_posts() ) {
while ( have_posts() ) : the_post();
var_dump( in_the_loop() ); // true
...
endwhile;
}
Therefore the is_singular() && in_the_loop() would only return true when:
-
You’re on a singular WordPress page like
example.com/sample-page/(a single Page; post typepage) and a CPT page like in your case (example.com/my_cpt/hello-post/) where the post type ismy_cpt. -
And that you’re in the loop for the main query.
So for example with your my_template_include_function() function, using the is_singular( 'my_cpt' ) would be sufficient and I don’t see why should you check for in_the_loop() there — single templates should display/start the loop for the main query, so by the time WordPress runs the template_include or single_template hook, that loop has not yet started or that you’re not yet in the main query’s loop.
Do correct me if I’m wrong/mistaken, though. 🙂
(Update) If your function (e.g. the my_template_include_function()) is actually being hooked to another hook which indeed runs in the main query’s loop, then yes, you can use in_the_loop() there. Example:
-
The filter: ( if in a (child) theme, this would be placed in the
functions.phpfile )function my_custom_single_template_part( $template ) { if ( is_singular( 'my_cpt' ) && in_the_loop() ) { return '/path/to/your/template-part.php'; } return $template; } add_filter( 'my_single_template_part', 'my_custom_single_template_part' ); -
The main loop:
if ( have_posts() ) { while ( have_posts() ) : the_post(); $template = apply_filters( 'my_single_template_part', 'template-parts/content' ); get_template_part( $template ); endwhile; }