I am pretty new in WordPress theme development and I’m not so into PHP (I came from Java and C#) and have the following situation in this custom theme
As you can see in the homepage I first show a section (named Articoli in evidenza) containing the featured posts (I’ve implemented it using a specific tag) and under it there is another area (named Ultimi Articoli) that contains the latest post that are not the featured post.
To do it I use this code:
<section id="blog-posts">
<header class="header-sezione">
<h2>Articoli in evidenza</h2>
</header>
<!--<?php query_posts('tag=featured');?>-->
<?php
$featured = new WP_Query('tag=featured');
if ($featured->have_posts()) :
while ($featured->have_posts()) : $featured->the_post();
/*
* Include the post format-specific template for the content. If you want to
* use this in a child theme, then include a file called called content-___.php
* (where ___ is the post format) and that will be used instead.
*/
get_template_part('content', get_post_format());
endwhile;
wp_reset_postdata();
else :
// If no content, include the "No posts found" template.
get_template_part('content', 'none');
endif;
?>
<header class="header-sezione">
<h2>Ultimi Articoli</h2>
</header>
<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>
<?php
if (have_posts()) :
// Start the Loop.
while (have_posts()) : the_post();
/*
* Include the post format-specific template for the content. If you want to
* use this in a child theme, then include a file called called content-___.php
* (where ___ is the post format) and that will be used instead.
*/
get_template_part('content', get_post_format());
endwhile;
else :
// If no content, include the "No posts found" template.
get_template_part('content', 'none');
endif;
?>
</section>
It works fine, but I have some doubts about the quality of this solution and how exactly it works.
To select all the featured posts, I use this line that creates a new WP_Query
object that defines a query having the specific tag featured
:
$featured = new WP_Query('tag=featured');
Then I iterate on this query result using its have_posts()
method.
So, from what I have understand, this is not the WordPress main query, but it is a new query created by me. From what I understand, it is better create a new query (as done) and not use the main query when I want perform this kind of operation.
Is it true, or am I missing something? If it is true, can you explain me, why it is better to create a new custom query and not modifying the WordPress main query?
Ok, going on. I show all the posts that don’t have the ‘featured’ tag. To do this, I use this code snippet, which on the contrary, modifies the main query:
<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>
<?php
if (have_posts()) :
// Start the Loop.
while (have_posts()) : the_post();
get_template_part('content', get_post_format());
endwhile;
else :
// If no content, include the "No posts found" template.
get_template_part('content', 'none');
endif;
?>
So I think, this is pretty horrible. Is it true?
UPDATE:
To do the same operation I found this function (in the great answer below) that I have added to functions.php
function exclude_featured_tag( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
}
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );
This function has a hook that is called after the query variable object is created, but before the actual query is run.
So, from what I have understand, it takes a query object as input parameter and modifies (actually filters) it by selecting all the posts excluding a specific tag (in my case the featured
tag posts)
So, how can I use the previous query (the one used to show the featured posts) with this function to show only the not featured posts in my theme? Or do I have to create a new query?