Skip Navigation

[Resolved] pre_get_post hook not changing the query on archive page

This support ticket is created 4 years ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

This topic contains 8 replies, has 2 voices.

Last updated by Elsie 4 years ago.

Assisted by: Beda.

Author
Posts
#1581437

The page in question is the archive on the post type "upcoming-classes"

hidden link

I have the 2 filters there which work fine but there's another filter I want to do that is outside of what's capable in the UI. I can do the query if I could modify the query itself.

Seeing other examples on the knowledge base I attempted to hook into pre_get_posts with a function to modify the query.

function my_get_posts( $query ) {
global $WP_Views;

if(!is_admin()&&$WP_Views->current_view == 1428){
$query->set('orderby', 'title');
$query->set('order', 'ASC');
$query->set('posts_per_page', 2);
}
return $query;
}
add_filter( 'pre_get_posts', 'my_get_posts' );

Now this isn't the modification I wanted to do. This was just to prove that I was hooking into the right place. This doesn't seem to change the query at all. I expected to see 2 results ordered by title. Instead the original query is ran. Nothing has changed.

In an attempt to debug I add die("<pre><h2>QUERY:</h2>".print_r($query,1)."</pre>"); before I return the query to see what's happening.

The output from that shows that it's changing the value in $query->query_vars['posts_per_page'] to 2 but $query->query['posts_per_page'] remains at 5. It's also changing the orderby and order values JUST in $query->query_vars but the results remain unaltered.

Again, the actual change I need to make to the query entails adding a more complex meta_query array that does some date comparisons outside of what's possible in the UI of the archive template. I just did this simple query change to verify I was in the right place. What am I missing?

#1581991

I don't think pre_get_posts is a filter, it's an action and hence you should add_action to it, not add_filter.
https://developer.wordpress.org/reference/hooks/pre_get_posts/

Can you reformulate the code according to the WordPress Core Codex, to see if this helps?

#1582619

I switched it to an action an it still has zero effect. I should have explained I tried both add_filter and add_action. I was thinking I may be assigning it to the wrong hook.

#1584229

To clarify my question... Is there a specific toolset hook that is overwriting my change to the query using "pre_get_posts"?

And if so... would it make more sense to modify the quote using that hook instead?

#1584911

It is an action, there is no possibility to switch this to a filter. That's how WordPress API works, it provides actions or filters, and they can't be "mixed" in this sense.

Toolset does not offer any hook on Archives, in fact pre_get_posts is the only hook that WordPress will offer for archives as far I know. Hence, Toolset should not overwrite it either.

You will see that when dumping the $query of pre_get_posts you get the whole query object which you can alter.
The WP_Query Object will hold query, query_vars, tax_query and many more properties.

According to the WP_Query Documentation, $query holds the query string that was passed to the $wp_query object by WP class.
$query_vars is an associative array containing the dissected $query: an array of the query variables and their respective values.

You will want to update the query_vars['posts_per_page'] value, for it to work properly (taking an example on the pagination)

function customize_query_var_on_archive_using_toolset( $query ) {
	$query->query_vars['posts_per_page'] = 1;
  error_log(print_r($query, true)); 
}
add_action( 'pre_get_posts', 'customize_query_var_on_archive_using_toolset' );

Does this help?

#1585631

Ok none of that worked.

Here's why... the pre_get_post hook only applied to the main query on the page. The filter form and the filter results are done in toolset and are subqueries. THAT is what I needed to hook into.

After reading through ALL the sourcecode I found the answer I was looking for and I'm posting it here in case someone else is trying to modify a query on toolset's archive filter view.

The file: /wp-views/embedded/inc/wpv-archive-loop.php defines a class: WPV_WordPress_Archive_Frontend

In that class definition it creates an action hook "wpv_action_apply_archive_query_settings";

The class hooks into the action 3 times with priorities 10,20, and 30.

If you need to modify the query on the archive filter view you need to hook into this action with a priority greater than 30.

My proof of concept allowed me to modify the query to return 1 result and sort by title ascending.

function modify_query($query, $archive_settings, $archive_id){
    if($archive_id==1428){//change this to the view ID of your archive page
        $query->set('orderby', 'title');
        $query->set('order', 'ASC');
        $query->set('posts_per_page', 1);
    }
}
add_action('wpv_action_apply_archive_query_settings','modify_query',31,3);

Using this hook it seems you can modify the query however you like.

#1586559

This is not an official API filter.
It could change depending on the internal development of the plugin.

However, I talked to View's Lead Developer and while he confirms that any hook that is not publicly documented should be managed as private, meaning it is open for change without prior notice, he also stated the hook to be stable enough for usage.

The hook runs on pre_get_posts too, the Toolset Developers just added it to have a centralized, single entry point for the WordPress Archives settings to be applied.

You can still use pre_get_posts safely.
But if you want to check what settings the WordPress Archive itself pushed to the query, in this case, you can use the hook (with the proper high enough priority as you already found out), or the very same pre_get_posts with also a high enough priority.

Note, we are not documenting the hook yet, however you can use it.
There is very little chance for it to change. However, I would also try as suggested by adding the pre_get_posts action, later (as with 30 or above).

Please let me know if I can help further!

#1586969

Thank you for your help but I want to repeat, pre_get_posts DOES NOT WORK to solve my problem. Regardless of the priority you set it at. The issue it seems to me is when I hook into pre_get_post it ONLY hooks to the main query.

The main query of the page is only returning a single post. It's withing that single post loop that wpv-archive-loop.php then does sub queries to find the archive posts based on the selected filters. pre_get_post does not hook into those subqueries at that level but the action "wpv_action_apply_archive_query_settings" is done at that level which is why I'm able to modify the query.

To explain my specific problem, I created a dropdown select form input in the filter that queries a month and year. 2020-04 for example. I hook into the "wpv_action_apply_archive_query_settings" action to add a meta_query to filter the results to only posts where the meta_field "wpcf-class-start-date" is between the first and last day of the selected month. In addition if NO year-month filter is selected the value of "All" is queries for which I then add the meta_query to limit to only posts where "wpcf-class-start-date" is after the current date. It may be a nice feature for the developer to specifically add a public hook to be applied at this level for this purpose and allow people to modify the archive filter query.

#1586971

My issue is resolved now. Thank you!

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.