I’m creating a plugin that adds a custom feed. I am using a pre_get_posts
filter to change the posts_per_page
query var to -1 (to get all items of a custom post type). However, if I dump the $wp_query
in the render function, posts_per_page
remains the default. I tested also changing posts_per_rss
to -1, and I do see that as changed in the query (though it, of course, doesn’t have any effect on the resulting posts). I also tried changing my theme to a default one and testing, but I had the same results. Can anyone explain why I can’t change the posts_per_page
query var?
defined( 'ABSPATH' ) OR exit;
if(!class_exists('My_Custom_Feeds'))
{
class My_Custom_Feeds {
protected $feed_slug = 'theslug';
function __construct() {
add_action( 'init', array($this, 'mcf_add_feed'));
add_filter( 'pre_get_posts', array($this, 'mcf_pre_get_posts'));
}
function mcf_add_feed() {
add_feed($this->feed_slug, array($this, 'mcf_render'));
}
function mcf_render(){
//just output query to ensure it is as expected - but it's not
global $wp_query;
var_dump($wp_query);
exit();
}
function mcf_pre_get_posts( $query ) {
if ( $query->is_main_query() && $query->is_feed( $this->feed_slug ) ) {
// modify query here to show all posts
$query->set( 'posts_per_page', -1);
$query->set( 'posts_per_rss', -1);
}
}
}
}
if ( class_exists('My_Custom_Feeds') ){
$my_custom_feeds = new My_Custom_Feeds();
}
Update one:
Realized I was using add_filter
instead of add_action
for pre_get_posts
. I’ve updated that, though I still see the same issue.
add_action( 'pre_get_posts', array($this, 'mcf_pre_get_posts'));
Update two (and final):
Per @ialocin’s answer, I realized changing the posts_per_page
query var is futile since it is overwritten by the posts_per_rss
option in a feed query (my scenario). So, the answer is to use a filter to alter that option. (-1 is not a valid posts_per_rss
value, thus the arbitrary one used below.)
function mcf_posts_per_rss( $option_name ) {
global $wp_query;
if ( $wp_query->is_main_query() && $wp_query->is_feed( $this->feed_slug ) ) {
return 100; //arbitrarily large value that, while not ideal, works for me
}
return $option_name;
}
Then in my plugin class constructor I added the following (and removed the pre_get_posts
action):
add_filter( 'pre_option_posts_per_rss', array( $this, 'mcf_posts_per_rss') );