How to exclude categories from Archive.php WordPress - php

I created a blognews.php page (it shows the last news with a monthly archive) with this code to exclude some categories.
$args = array(
'post_type' => 'post',
'post_status' => 'publish',
'category__in' => 54,
'category__not_in' => 3 ,
'order' => 'DESC'
);
$query = new WP_Query($args);
and it works, the articles under this category aren't displayed.
But when I do the same thing to archive.php and I click a month, I see the posts under the excluded category.
I tried this but it doesn't work:
<?php if ( have_posts() ) : ?>
<?php
query_posts( array( 'category__and' => array(54), 'posts_per_page' => 20, 'orderby' => 'title', 'order' => 'DESC' ) );
while ($query->have_posts()):
$query->the_post();
get_template_part( 'template-parts/content', 'excerpt' );
Is there an easy way to exclude more categories from the blognews.php page and the archive? What's wrong with my code? Or show only a specific category it will be good too.

Add this code to the functions.php file
function exclude_category( $query ) {
if ( $query->is_archive() && $query->is_main_query() ) {
$query->set( 'cat', '-3' );
}
}
add_action( 'pre_get_posts', 'exclude_category' );
Here all conditions where is_archive is true:
if ( $this->is_post_type_archive
$this->is_date
$this->is_author
$this->is_category
$this->is_tag
$this->is_tax )
$this->is_archive = true;

Related

Wordpress wp_query not showing some posts

I'm trying to get 5 posts of one category and paginate them, but my loop doesn't get some posts. In this case, I put 5 posts to retrieve but the loop only returns 2 and sometimes 3.
Finally, when I'm trying to use pagination it doesn't work.
Here is my code:
<?php
// Protect against arbitrary paged values
$paged = ( get_query_var( 'paged' ) ) ? absint( get_query_var( 'paged' ) ) : 1;
$args = array(
'category__in' => array( 11 ),
'category__not_in' => '',
'posts_per_page' => 5,
'post_type' => 'post',
'post_status'=>'publish',
'paged' => $paged,
);
$the_query = new WP_Query($args);
?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
$the_query->the_post();
// Post content goes here...
//
echo '
<h3 class="tituliNota">
<a href="'.get_permalink().'" class="noteTitle">
<b>'.the_title( ' ', ' ', false ).'</b></a></h3>';
get_the_category();
wp_reset_postdata();
endwhile; ?>
<div class="pagination">
<?php
echo paginate_links( array(
'format' => 'page/%#%',
'current' => $paged,
'total' => $the_query->max_num_pages,
'mid_size' => 5,
'prev_text' => __('« Prev Page'),
'next_text' => __('Next Page »')
) );
?>
</div>
The main query runs before the template is loaded, and WordPress decides what template to load based on the results of that query.
You say your default posts_per_page is set to 5, and there are 2 or 3 posts in that category, so as far as WordPress knows, there is no page 2. Your custom query that you run in the template with a different posts per page setting is unrelated to the main query.
The solution is to make adjustments to the main query before the template is loaded, via the pre_get_posts action. This would go in your theme's functions.php file
function category_posts_per_page( $query ) {
if ( !is_admin()
&& $query->is_category()
&& $query->is_main_query() ) {
$query->set( 'posts_per_page', 5 );
}
}
add_action( 'pre_get_posts', 'category_posts_per_page' );

Wordpress short code to display all child page by parents ID

I'm working on a short code for loop through parents ID and display all child page, but I'm not quite sure how to make the loop and make it more custom.
Here's my code:
add_shortcode( 'home-page-listing', 'get_list' );
function get_list( $atts ) {
ob_start();
$atts = shortcode_atts( array(
'ids' => ''
), $atts );
if($atts['ids']!='')
{
$id_array = explode(',',$atts['ids']);
$homePages = new WP_Query( array(
'post_type' => 'page',
'post__in'=>$id_array,
'order' => 'ASC',
'orderby' => 'post__in',
'posts_per_page' => -1
) );
if ($homePages->have_posts()){?>
<div class="">
<?php while ( $homePages->have_posts() ) : $homePages->the_post(); ?>
//here's html template code
<?php endwhile;
wp_reset_postdata(); ?>
</div>
}
}
}
Right now I can use [home-page-listing id=1,2,3,4] to display all select page ID, but I would like to make like this:
[home-page-listing parentID=4]
loop through all child page and display to the font, instead go check all the page id to display.
Thanks!
it's simple used post_parent Arguments of WP_Query. Please check below example
$homePages = new WP_Query( array(
'post_type' => 'page',
'post_parent'=>$parentID,
'order' => 'ASC',
'orderby' => 'parent',
'posts_per_page' => -1
) );
For more information of WP_Query click here

Get featured products in Woocommerce 3

I want to add Featured products for upsell (or Recent Products OR Best Selling Products) in New order Email template. It works like Upsell with email marketing. How do I add it to woocommerce email template so that there is a section in the end of the email which shows my featured/Recent/best selling products. I tried using this code in my New order Email template but nothing works. I use all latest version of wordpress n woocommerce.
$args = array(
'post_type' => 'product',
'meta_key' => '_featured',
'meta_value' => 'yes',
'posts_per_page' => 1
);
$featured_query = new WP_Query( $args );
if ($featured_query->have_posts()) :
while ($featured_query->have_posts()) :
$featured_query->the_post();
$product = get_product( $featured_query->post->ID );
// Output product information here
endwhile;
endif;
wp_reset_query(); // Remember to reset
Since Woocommerce 3, the products following properties:
"featured",
"stock status",
"catalog visibility"
"rating system"
are now stored like a post term under 'product_visibility' taxonomy, for better performances. So old postmeta data doesn't work anymore.
To make your code working you need instead to make a tax_query this way:
function custom_featured_products(){
$query = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1 ,
'tax_query' => array( array(
'taxonomy' => 'product_visibility',
'field' => 'term_id',
'terms' => 'featured',
'operator' => 'IN',
) )
) );
$featured_product_names = array();
if ( $query->have_posts() ): while ( $query->have_posts() ): $query->the_post();
$product = wc_get_product( $query->post->ID );
$featured_product_names[] = $product->get_title();
endwhile; wp_reset_query();endif;
// Testing output
echo '<p>Featured products: ' . implode(', ', $featured_product_names) . '</p>';
}
// Displaying the featured products names in new order email notification
add_action ('woocommerce_email_customer_details', 'new_order_featured_products_display', 30, 4 );
function new_order_featured_products_display( $order, $sent_to_admin, $plain_text, $email ){
// Only for "New Order" email notification
if( 'new_order' != $email->id ) return;
custom_featured_products(); // calling the featured products function output
}
This code goes on function.php file of your active child theme (or theme).
Tested and works.
Updated related to your comments…
Added the code in a function that is called via a hooked function in "New order" email notification.
To get the product image use: $product->get_image( 'shop_thumbnail' );
To get the product link use : $product->get_permalink();
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
echo '<p>'.get_the_title().'</p>';
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->

sort posts based on meta key in a taxonomy archive page

I am using the below code to sort posts based on my meta key sub_seminars_0_start_date. The code works fine as it gets all the posts from portfolio post_type and then sorts them based on my meta key. However when I through a taxonomy query it displays nothing, a blank page with header and footer.
<?php
$args = array(
'post_type' => 'dt_portfolio',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => 'dt_portfolio_category',
'field' => 'slug',
'terms' => '',
),
),
'meta_key' => 'sub_seminars_0_start_date',
'orderby' => 'meta_value_num',
'order' => 'ASC',
);
$query = new WP_Query( $args ); ?>
How can I sort my posts that are in the taxonomy archive page ?
function change_order_for_events( $query ) {
//only show future events and events in the last 24hours
$yesterday = date('Ymd');
if ( $query->is_main_query() && (is_tax('dt_portfolio_category') || is_post_type_archive('dt_portfolio')) ) {
$query->set( 'meta_key', 'sub_seminars_0_start_date' );
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'order', 'ASC' );
//Get events after 24 hours ago
$query->set( 'meta_value', $yesterday );
$query->set( 'meta_compare', '>' );
//Get events before now
//$query->set( 'meta_value', current_time('timestamp') );
//$query->set( 'meta_compare', '<' );
}
}
add_action( 'pre_get_posts', 'change_order_for_events' );
this code in function.php will sort your posts based on a specific meta key value.
sub_seminars_0_start_date
I have created a custom taxonomy Seminar_Venues but the above code won’t work for that even after adjustin the parameters. Can you look
function pre_get_posts_hook($wp_query) {
if( is_admin() ) {
return $wp_query;
}
if ($wp_query->is_main_query() && ( is_category() || is_archive() ))
{
$wp_query->set( 'orderby', 'meta_value' );
$wp_query->set( 'meta_key', 'sub_seminars_0_start_date' );
$wp_query->set( 'order', 'ASC' );
return $wp_query;
}
}
add_filter('pre_get_posts', 'pre_get_posts_hook' );
This worked for me to sort the posts based on a custom field mate key

Exclude all sub categories from wp_query

I've been searching high and low for and answer to this, but I'm not actually sure it's possible!
I have a WP_Query that pulls posts from almost everything, however, I wish to exclude a specific category and/or all it's sub categories.
Searching around people are yet to find a solution for this.
Here's my query so far:
$args = array(
'post_type' => 'sell_media_item',
'cat' => -98,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php $loop = new WP_Query( $args ); ?>
I thought just excluding cat 98 would grab all the sub categories too, but apparently not.
I've tried using:
category__not_in, depth=0, parent=0 and even an adaptation of this, with no luck.
Any ideas?
[EDIT]
I'm using a custom taxonomy called Collections, so putting 'collection' => 'vip' into the query means it will only show this collection. I'm thinking if there's a way of reversing this so it excludes the collection instead?
As it's not possible to list all of the categories that will appear here as they will be changing all of the time.
[EDIT 2]
After the discussion in the comments below, here's the updated code.
$ex = array(
'taxonomy' => 'collection',
'child_of' => 98,
'hide_empty' => 0
);
$categories = get_categories($ex);
$categoriesToExclude = array();
foreach ($categories as $category) {
$categoriesToExclude[] = $category->cat_ID;
}
echo('<pre>'); var_dump($categories);
$args = array(
'post_type' => 'sell_media_item',
'category__not_in' => $categoriesToExclude,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php echo('<br /><pre>'); var_dump($args); ?>
<?php $loop = new WP_Query( $args ); ?>
I would get the list of all sub categories with get_categories() and then build a 'cat' exclusion array based on the results.
$args = array('parent' => 98);
$categories = get_categories($args);
$categoriesToExclude = array();
foreach ($categories as $category) {
$categoriesToExclude[] = $category->cat_ID;
}
$args = array(
'post_type' => 'sell_media_item',
'category__not_in' => $categoriesToExclude,
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
); ?>
<?php $loop = new WP_Query( $args ); ?>
This is just an example, you may have to modify it slightly to fit your needs.
So!
It appears I was trying to do the impossible. I couldn't get this script working for the life of me. So I tried a different angle. Instead of excluding a custom taxonomy and its terms, I decided to move all of my other terms into a parent term and just called that instead.
Here's the code if anyone's interested...
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'sell_media_item',
'taxonomy' => 'collection',
'term' => 'clubs',
'orderby' => 'desc',
'paged' => $paged,
'posts_per_page' => 20
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : while ($loop->have_posts()) : $loop->the_post(); ?>
I wrote my own function in order to exclude subcategory posts from the loop, using tips from the above post and elsewhere.
In my theme archive.php file, above the loop, I list the subcategories (optional):
<?php
$current_cat = get_queried_object();
$args = array( 'parent'=>$current_cat->term_id, 'child_of' => $current_cat->term_id, );
$categories = get_categories( $args );
foreach($categories as $category) { ?>
<h2><?php echo $category->name ;?></h2>
<p> etc....</p>
<?php } ?>
In my functions.php file, I've added the following custom function using pre_get_posts:
add_action( 'pre_get_posts', 'main_query_without_subcategory_posts' );
function main_query_without_subcategory_posts( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
// Not a query for an admin page.
// It's the main query for a front end page of your site.
if ( is_category() ) {
//Get the current category
$current_category = get_queried_object();
//get the id of the current category
$current_cat_id = $current_category->term_id;
//find the children of current category
$cat_args = array( 'parent'=>$current_category->term_id, 'child_of' => $current_category->term_id, );
$subcategories = get_categories( $cat_args );
//Get a list of subcategory ids, stick a minus sign in front
$subcat_id = array();
foreach($subcategories as $subcategory) {
$subcat_id[] = " -". $subcategory->term_id;
}
//join them together as a string with a comma seperator
$excludesubcatlist = join(',', $subcat_id);
//If you have multiple parameters, use $query->set multiple times
$query->set( 'posts_per_page', '10' );
$query->set( 'cat', ''.$current_cat_id.','.$excludesubcatlist.'' );
}
}
}
Then in the archive.php, below the subcategories, I've added the regular WordPress loop which is now being modified by the above function:
<?php while (have_posts() ) : the_post(); ?>
<h2><?php the_title();?></h2>
<p> etc....</p>
<?php endwhile;?>
Though the WordPress codex says that using "category__in" will exclude posts from subcategories, that didn't work for me and subcategory posts were still showing.
https://codex.wordpress.org/Class_Reference/WP_Query#Category_Parameters
https://developer.wordpress.org/reference/hooks/pre_get_posts/

Categories