#20647 closed defect (bug) (invalid)
get_post_type() returns nothing on custom post type archive pages with custom query and no results
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Post Types | Version: | 3.3.2 |
| Severity: | normal | Keywords: | needs-patch |
| Cc: | xoodrew@… |
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 (8)
- Milestone Awaiting Review deleted
- Resolution set to invalid
- Status changed from new to closed
wp_reset_postdata() does exactly what you want: restores the $post global from the main query. Works for new WP_Query() too.
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.
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.
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().
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.
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.
comment:8
DrewAPicture — 13 months ago
- Cc xoodrew@… added

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().