Cesar Schrega
Cesar Schrega

Reputation: 81

pre_get_posts main query and post query forwarding empty values in object

I'm trying to add a meta_query to some of my post types (post, eventos, agenda).

I had some experience using pre_get_posts, I guessed i would just hook on it and check that whenever the post type was in the array, I would add the meta.

I'm not able to always get the post type thou, the situation in details:

Loading Front page (static page defined), Contains 3 queries inside: 1 for posts (used query_posts() and only defined posts_per_page, since post type "post" is default). 2 other queries are get_posts() since they wont require pagination.

Right now I'm just hookin into the action and dumping the provided object:

function my_pre_get($query) {
    var_dump($query);
}
add_action( 'pre_get_posts', 'my_pre_get'); 

What happens is, the action runs at every single query performed for the page load (main query, my query_posts and the get_posts) But on main query I get all empty values inside the object. On query_posts I only get the value for pagination I've set. On the get_posts I get the post types.

Right now I'm not sure what route to take... I can try to implement some complex checking to find out the type of page I'm on and then assume post_type is post, but this seems like a terrible inefficient and troublesome idea.

Is there an alternative way to always get the post type when a query is about to run and modify it?

I have also tried hook into parse_query, but same results. :/

----edit As it was requested, the front page template code (thou i don't think that's helpful for the topic at all):

<?php /*** Template Name: Front Page */ ?>
<!doctype html>
<html <?php language_attributes(); ?> >

<head>
    <?php wp_head(); ?>
</head>

<body>

    <?php wp_footer(); ?>

</body> 

The action is added inside functions.php which is pretty much whats above already.

Upvotes: 0

Views: 4808

Answers (3)

Valentyn Ilinov
Valentyn Ilinov

Reputation: 1

I think this can help:

function faq_query($query){

    if(isset($query->query['post_type'])) {
        if($query->query['post_type'] === 'faqs') {
            $meta_key = 'your_meta_key';
            $meta_query = array(
                            'relation' => 'OR',
                            'meta_value_num' => array(
                                'key'     => $meta_key,
                                'compare' => 'EXISTS ',
                            ),
                            array(
                                'key'     => $meta_key,
                                'compare' => 'NOT EXISTS',
                            ),
                        );
                        $query->set( 'orderby', 'meta_value_num' );
                        $query->set( 'meta_query', $meta_query );
        }
    }

}
add_action('pre_get_posts', 'faq_query', 1 );

Upvotes: 0

Cesar Schrega
Cesar Schrega

Reputation: 81

I did a deep loop into class-wp-query.php and that's the natural behavior of pre_get_posts.

"Default" query parameters, like post type, default items_per_page... etc, are all set in a really complex "IF" sets., after the pre_get_posts actions.

So, in a 'default' front end query, "post_type" will never be available as a query_var, no matter which hook is used. It is needed to go trough workarounds to find out if the current post type is 'post' in a main_query.

In a clear answer to my question: No

Upvotes: 0

Paul
Paul

Reputation: 1432

Here is a query that I used recently that checks for the post type

function faq_query($query){

    if(isset($query->query['post_type'])) {
        if($query->query['post_type'] === 'faqs') {
            $query->set('posts_per_page',-1);
            $query->set('orderby', 'menu_order');
        }
    }

}
add_action('pre_get_posts', 'faq_query', 1 );

Does this help?

Upvotes: 0

Related Questions