WordPress.org

Make WordPress Core

Opened 7 years ago

Closed 7 years ago

Last modified 21 months ago

#20647 closed defect (bug) (invalid)

get_post_type() returns nothing on custom post type archive pages with custom query and no results

Reported by: MikevHoenselaar Owned by: MikevHoenselaar
Milestone: Priority: normal
Severity: normal Version: 3.3.2
Component: Posts, Post Types Keywords: needs-patch
Focuses: Cc:

Description

As following:
I open a custom post type archive page. In my case domain.nl/partners.
Everything works fine here.
We have a custom filter and use ?bg={number}?country={number} to filter on custom field on that archive page.

We use the pre_get_posts action for that. We set the meta_query query var via ->set().

When we do this and use a {number} in the $_GET that doesn't exists. Obviously we have 0 results.
So $post remains empty in the get_posts() function.

In a lot of plugins and in this case WordPress SEO of Yoast is a function get_post_type() being used. The function relies on $post to function properly.

When there are no results, no $post, no post_type. But I believe we can work with the queried_vars here.
get_query_var( 'post_type' ); to fix it. My solution:

function get_post_type( $the_post = false ) {

global $post;
if ( false === $the_post )

$the_post = $post;

elseif ( is_numeric($the_post) )

$the_post = get_post($the_post);

if ( is_object($the_post) )

return $the_post->post_type;

else

return get_query_var ('post_type');

return false;

}

Change History (9)

#1 @scribu
7 years ago

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

If you're using query_posts() and it whipes out the $post global, the solution isn't to patch get_post_type(), but to call wp_reset_query() or wp_reset_postdata().

#2 @scribu
7 years ago

wp_reset_postdata() does exactly what you want: restores the $post global from the main query. Works for new WP_Query() too.

#3 @scribu
7 years ago

Oh, and if you absolutely need a function that uses the query vars, there's get_queried_object(), which will return the post type object, if called from a post type archive.

Let's keep get_post_type() tied to the $post global, for the sake of everyone's sanity.

#4 @MikevHoenselaar
7 years ago

I expected that get_post_type() would give me the post_type of the query I did. It's post only. If the main_query on the archive page isn't returning anything get_post_type() isn't useful now. But it can be useful to get a post_type.
So you are saying that Yoast will have to edit his plugin and use a !empty($post_type) after using get_post_type()?

I know that you can have your own if, then, elses in your plugin. And probably Yoast shouldn't take for granted that there always is a $post_type returned from get_post_type().
But I believe get_post_type can be better :-).

Adding this will make sure that I always will get a post_type if there is one.

#5 @scribu
7 years ago

Here's what the docs say:

/**
 * Retrieve the post type of the current post or of a given post.
 *
 * @since 2.1.0
 *
 * @uses $post The Loop current post global
 *
 * @param mixed $the_post Optional. Post object or post ID.
 * @return bool|string post type or false on failure.
 */
function get_post_type( $the_post = false ) {

You should think of it as belonging to the same family as get_post_status() and get_the_title().

#6 @scribu
7 years ago

Also note that get_query_var( 'post_type' ) can return an array. That's probably something most plugins aren't prepared for either.

So, my suggestion is that they should decide what they want: the post type of a certain post or the post type from the query vars? In the unlikely case when they would want both, they can just call both functions.

#7 @scribu
7 years ago

I would actually be for deprecating get_post_type(), since the name is misleading and it's not that useful as a template tag either. Plus you can just call get_post()->post_type now.

#8 @DrewAPicture
7 years ago

  • Cc xoodrew@… added

#9 @sicle
21 months ago

I know this ticket is closed, however it still shows up as the first page on Google when searching for 'get_post_type returns empty or nothing', so I thought I'd share som more general insight on get_post_type() returning nothing in a more general sense.

I had some troubles with get_post_types() as well, turns out it had to do with permalinks caching.
For me the fix was going to Settings->Permalinks and just hitting 'Save Changes', it updated the permalinks and saw my post types again.

Worth noting, all other methods also resulted in empty results, as it simply couldn't query anything and as such get_post_type() is also empty.

I actually run into empty query problems more often during theme development, before you try changing your code, just try to update the permalinks, fixes a lot of things.

Note: See TracTickets for help on using tickets.