WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 5 years ago

#34513 closed defect (bug) (invalid)

is_single() or is_singular() are not running filters on the queried object

Reported by: LindsayBSC Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.3.1
Component: Query Keywords: close
Focuses: Cc:

Description

I ran a basic piece of code that was meant to do the following:
If the page I am looking at is the single post for a specific post type (events), append an anchor tag and some text to the title.

I did this by using the_title filter and the is_singular() conditional. According to the codex for is_singular() and is_single it says that it will only run the code on the queried object (the single post for the specific post type loop).

Expected Results:
I expected to see my new content appended to the title of the post that was in that specific post type

Unexpected Results:
I saw my new content appended to every single item that was in a WP loop including menu items. This only happens on the single view of the post, however. So if you go to domain.com/events/a-single-post you would see my appended anchor tag all over the place. If you got to the single view for any other post type, however, you do not see this.

What this tells me:
This tells me that there is something wrong with those two conditionals where they are actually working, but they are not returning the proper post data. I have not yet looked into the source of those two functions so I can not say more than that.

Here is a gist of my code. This has been tested on a vanilla WP install and confirmed
https://gist.github.com/Lindsayanng/5b18ace5b2427f72c307

Screenshot attached so you can see what I was seeing.

Attachments (1)

Screen Shot 2015-10-30 at 4.14.40 PM.png (856.9 KB) - added by LindsayBSC 5 years ago.
Visual representation of results of weird is_single()/is_singular() conditional

Download all attachments as: .zip

Change History (4)

@LindsayBSC
5 years ago

Visual representation of results of weird is_single()/is_singular() conditional

#1 @mark-k
5 years ago

  • Keywords close added

You are probably doing it wrong. is_singular return true with the page that is being handled is singular and it will still be true everywhere during the processing of the page no matter in which specific loop you are at the moment.
You probably need to remove the filter after it is used the first time, or check if your current loop is the main loop.

#2 @LindsayBSC
5 years ago

Are you certain that this is the main purpose of the function? Most other conditionals check if you are on that page AND the query is the query for the conditional. For instance, the codex says: "If the $post_types parameter is specified, the function will additionally check if the query is for one of the post types specified." (similarly stated on the developer.wordpress.org record)

Every single documentation for the conditionals says it will also check if the query is also for what is specified (it makes sense to). If this is not how is_single() or is_singular() is meant to work, then I see some disparity between them and all of the other conditionals.

\* also yes, my loop I was trying to add the filter to is the main loop. As I said, it did the same thing on a vanilla install.

How is this already resolved?

#3 @johnbillion
5 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

The issue isn't with is_singular() or is_single() - the issue is that your conditional logic affects all queries on the page instead of just the main query.

The template conditional functions refer to the main query (ie. the main loop), but you're not accounting for the fact that not every query is the main query.

Your conditional logic should use is_main_query() and should look something like this:

function my_add_custom_content( $title) {
	if ( is_main_query() && is_singular( 'events' ) ):
		$postID = get_the_ID();
		$html = '<a href="#" class="goingLink setGoing" id="'.$postID.'" data-value="'. $postID .'">I\'m Going</a><div id="fb-root"></div>';
		$title .= $html;
	endif;

	return $title;
}
Note: See TracTickets for help on using tickets.