admin管理员组

文章数量:1327849

I'm using example code for a templating system.

Page at this address: /my_cpt/hello-post/.

Cannot understand why is_singular( 'my_cpt' ) is true while in_the_loop() is false.

Within the page template, it seems like The Loop "works":

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();
        ?>
        <h2><a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
        <?php
    } 
} 

I guess my question is when are is_singular() && in_the_loop() both true?

And when I run if ( have_posts() ) { while ( have_posts()... is that in the loop or is it creating the loop?

Update

Partly it has to do with which filter is being hooked in the function/method which performs the if && test.

The example above is being used with the template_include hook, which is getting run for pages, posts and maybe even links, menus, media, etc. So that would be why both tests are necessary.

The filter looks like:

add_filter( 'template_include', array( __CLASS__, 'my_template_include_method' ) );

or if it was not calling a class method would just be:

add_filter( 'template_include', 'my_template_include_function' );

The full method/function looks like:

public static function my_template_include_function( $original_template ) {
    if ( is_singular( 'my_cpt' ) && in_the_loop() ) {
        return wpbp_get_template_part( MMC_TEXTDOMAIN, 'content', 'my_template', false );
    }

    return $original_template;
}

The wpbp_get_template_part is from a plugin boilerplate I recently discovered called Wordpress Plugin Boiler Plate.

Since I'm looking, at the moment, a singular post, I can hook into single_template like this:

add_filter( 'single_template', array( __CLASS__, 'my_single_include_function' ) );

It looks like this:

public static function my_single_include_function( $single_template ) {
    global $post;

    if ( 'my_cpt' === $post->post_type ) {
            return wpbp_get_template_part( MMC_TEXTDOMAIN, 'single', 'my_template', false );
    }

    return $single_template;
}

The templates themselves look like: templates/content-my_template and templates/single-my_template.

I'm using example code for a templating system.

Page at this address: http://project.test/my_cpt/hello-post/.

Cannot understand why is_singular( 'my_cpt' ) is true while in_the_loop() is false.

Within the page template, it seems like The Loop "works":

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();
        ?>
        <h2><a href="<?php the_permalink(); ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
        <?php
    } 
} 

I guess my question is when are is_singular() && in_the_loop() both true?

And when I run if ( have_posts() ) { while ( have_posts()... is that in the loop or is it creating the loop?

Update

Partly it has to do with which filter is being hooked in the function/method which performs the if && test.

The example above is being used with the template_include hook, which is getting run for pages, posts and maybe even links, menus, media, etc. So that would be why both tests are necessary.

The filter looks like:

add_filter( 'template_include', array( __CLASS__, 'my_template_include_method' ) );

or if it was not calling a class method would just be:

add_filter( 'template_include', 'my_template_include_function' );

The full method/function looks like:

public static function my_template_include_function( $original_template ) {
    if ( is_singular( 'my_cpt' ) && in_the_loop() ) {
        return wpbp_get_template_part( MMC_TEXTDOMAIN, 'content', 'my_template', false );
    }

    return $original_template;
}

The wpbp_get_template_part is from a plugin boilerplate I recently discovered called Wordpress Plugin Boiler Plate.

Since I'm looking, at the moment, a singular post, I can hook into single_template like this:

add_filter( 'single_template', array( __CLASS__, 'my_single_include_function' ) );

It looks like this:

public static function my_single_include_function( $single_template ) {
    global $post;

    if ( 'my_cpt' === $post->post_type ) {
            return wpbp_get_template_part( MMC_TEXTDOMAIN, 'single', 'my_template', false );
    }

    return $single_template;
}

The templates themselves look like: templates/content-my_template and templates/single-my_template.

Share Improve this question edited Aug 2, 2020 at 21:39 MikeiLL asked Aug 2, 2020 at 15:03 MikeiLLMikeiLL 5791 gold badge8 silver badges22 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

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:

  1. You're on a singular WordPress page like example/sample-page/ (a single Page; post type page) and a CPT page like in your case (example/my_cpt/hello-post/) where the post type is my_cpt.

  2. 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:

  1. The filter: ( if in a (child) theme, this would be placed in the functions.php file )

    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' );
    
  2. 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;
    }
    

本文标签: loopWhen and Why is issingular(39mycpt39) true while intheloop() is false