I have a custom-post-type archive (archive-rg_blog.php) with two loops in it. One of the loops I’d like to filter with the below code. It’s just a basic loop for all posts, and I just need to set it to return all posts instead of the custom posts it’d return by default.
The other loop needs to pull the title and content from a specific custom post. The below seems to be filtering the second loop too, and so that it returns nothing at all.
function blog_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_post_type_archive('rg_blog')) {
$query->set('post_type', 'post');
}
}
}
add_action('pre_get_posts','blog_filter');
And this is the loop that returns nothing:
<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>
Edit: Just to clarify, this is what I’m trying to do.
///loop 1, queries a specific post
///loop 2, a normal loop filtered with pre_get_posts, which should return all posts.
///loop 3, also queries a specific post
So I need to add the filter before loop 2, and remove it again before loop 3. I’ve tried to add the filter into the archive template in the appropriate place, but loop 2 then fails to return all posts.
Edit #2: Here’s the whole loop in action. It’s the SECOND loop that needs to be filtered.
<?php get_header(); ?>
<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>
<!-- Main Loop (All Posts) -->
<?php function blog_filter($query) {
if ( !is_admin() && $query->is_main_query()) {
if ($query->is_post_type_archive('rg_blog')) {
$query->set('post_type', 'post');
}
}
}
add_action('pre_get_posts','blog_filter');?>
<?php $post = $posts[0]; $c=0;?>
<?php if (have_posts()) : ?><?php while (have_posts()) : the_post(); ?>
<!--Featured Post-->
<?php $c++;
if( !$paged && $c == 1) :?>
<!--stuff-->
<!--Other Posts-->
<?php else :?>
<!--the remaining posts-->
<?php endif;?>
<?php endwhile; endif; ?>
<!-- The end of the loop -->
<?php remove_action('pre_get_posts','blog_filter');?>
<!--third loop, a repeat of loop 1-->
<?php // blog title and description query
$post_id = 4606;
$queried_post = get_post($post_id);
$title = $queried_post->post_title;?>
<h1><?php echo $title;?></h1>
<?php echo $queried_post->post_content;?>
<?php get_footer() ?>
Add the filter where you need it and remove it afterwards.
You can also make your action self-removing:
Your code, reorganized:
I have not tested that but I think it will work better. Hopefully, I don’t have any syntax errors.
Edit:
I took a closer look at your code (while not watching “Defiance”) and notices a couple of things.
it before the page template loads– probably in
functions.php
. Butmy understanding of the question is that the filter is meant for a
secondary Loop. That would mean that that “main query” check is
wrong.
get_post
by ID, so for those thefilter is irrelevant.
So, to filter that main query you need this in
functions.php
:And no add or remove actions anywhere else. I am not sure that is what you want though. The two
get_post
calls should be unaffected.I would suggest checking the
is_post_type_archive
before adding the filter:This way, it won’t run on every page load.
Try removing the filter before the second query: