Woocommerce products from category loop - php

In Woocommerce, I Need some help with this custom product loop, in my code my result is : how it looks like
The loop doesn't stop and it is looping the same products for three or four times.
The code I am using is here :
<div class="container">
<div id="default_products_page_container" class="wrap wpsc_container">
<?php
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 );
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 );
$cat = get_query_var( 'product_cat' );
$args = array( 'post_type' => 'product', 'posts_per_page' => 5, 'product_cat' => $cat, 'orderby' => 'rand' );
$loop = new WP_Query( $args );
?>
<div class="wpsc_default_product_list">
<?php
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12">
<div class="default_product_display product_view_<?php echo get_permalink( $loop->post->ID ); ?>group">
<a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>"/>
<?php if (has_post_thumbnail( $loop->post->ID ))
{
?>
<div class="product-image-thumb">
<img src="<?php echo the_post_thumbnail_url( $loop->post->ID );?>"/>
</div>
<?php
} else
{?>
<div class="product-image-thumb">
<a>
<img src="<?php echo woocommerce_placeholder_img_src();?>"/>
</a>
</div>
<?php } ?>
</div>
</div>
<?php endwhile; ?>
</div>
<?php wp_reset_query(); ?>
</div>
</div>

I Hope this code gonna help you guys :)
<ul class="products">
<?php
$args = array(
'product_cat' => 'Shampoo',
'posts_per_page' => 4,
'orderby' => 'rand'
);
$loop = new WP_Query($args);
while ($loop->have_posts()) : $loop->the_post();
global $product; ?>
<div class="row">
<!-- <h2>Shampoo</h2> -->
<li class="product">
<a href="<?php echo get_permalink($loop->post->ID) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
<?php woocommerce_show_product_sale_flash($post, $product); ?>
<?php if (has_post_thumbnail($loop->post->ID)) echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog');
else echo '<img src="' . woocommerce_placeholder_img_src() . '" alt="Placeholder" width="300px" height="300px" />'; ?>
<h3><?php the_title(); ?></h3>
<span class="price"><?php echo $product->get_price_html(); ?></span>
</a>
<?php woocommerce_template_loop_add_to_cart($loop->post, $product); ?>
</li>
</div>
<?php endwhile; ?>
<?php wp_reset_query(); ?>
</ul>
<!--/.products-->

You need to do a tax query instead this way:
$loop = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 5,
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug', // Or 'term_id' or 'name'
'terms' => get_query_var( 'product_cat' ), // A slug term
// 'include_children' => false // or true (optional)
)),
'orderby' => 'rand'
) );
Tested and works on Woocommerce product category archive pages…

Your code should work, although it will take all products in the loop (including those marked as "draft" when you are logged in). You can define only published by adding 'post_status' => 'publish' to your argument variable.
And you should take a look at those anchor tags (specifically the close part)

Related

Duplicate Posts In Custom Post Type by Taxonomy

I have a Custom Post Type called Products (not WooCommerce). The user selects the Categories using an ACF Taxonomy Field. I'm trying to get each Product per selected Category but some of the products are in multiple categories so when I am looping through the rows they are printing multiple times.
<?php
$product_categories = get_field( 'product_filter_categories' );
$custom_taxonomy='product_category';
$custom_terms = $product_categories;
foreach($custom_terms as $custom_term) :
wp_reset_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => $custom_taxonomy,
'field' => 'slug',
'terms' => $custom_term->slug,
),
),
);
$loop = new WP_Query($args);
if($loop->have_posts()) :
$product_coming_soon_image = get_field( 'product_coming_soon_image' );
while($loop->have_posts()) : $loop->the_post();
$termsArray = get_the_terms( $post->ID, "product_category" );
$termsString = "";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug.' ';
} ?>
<div class="<?php echo $termsString; ?> isotope-item">
<a href="<?php the_permalink(); ?>">
<?php if ( has_post_thumbnail() ) : ?>
<img src="<?php the_post_thumbnail_url('') ?>" class="lazy" alt="<?php the_title() ?>" loading="lazy" width="240" height="240">
<?php else : ?>
<img src="<?php echo esc_url( $product_coming_soon_image['sizes']['our-products'] ); ?>" alt="<?php echo esc_attr( $product_coming_soon_image['alt'] ); ?>" loading="lazy" width="240" height="240" />
<?php endif; ?>
</a>
<h3><?php the_title(); ?></h3>
</div>
<?php
endwhile; ?>
<?php
endif;
endforeach; ?>
</div>
I can't determine where the duplicates are coming from.
Ok, so what you are doing is :
getting some terms
looping on terms
getting products by the term
looping on products for display
So indeed, if a product is associated with multiple terms in the loop, they'll appear multiple times this way.
You should remove the first foreach, and query product by multiple terms, then loop on the wp_query results. This way you won't have duplicates:
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => $custom_taxonomy,
'field' => 'slug',
'terms' => array_column($custom_term, 'slug'),
),
),
);
If you really need to loop on your terms, and query product on each loop: you'll need to store all queried post ids in an array from initiated outside the loop. And add to the query "post not in: ids" with this array of ids "already queried".
I was able to remove the duplicates by creating an empty array just before the first foreach and then checking if the current post ID was in that array while looping. If the the current post id was not in the array, add it to the array and show the product. If the current post id is in the array, skip it.
Updated Code
$product_categories = get_field( 'product_filter_categories' );
$custom_taxonomy = 'product_category';
$custom_terms = $product_categories;
$displayed_products = array();
foreach($custom_terms as $custom_term) :
wp_reset_query();
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => $custom_taxonomy,
'field' => 'slug',
'terms' => $custom_term->slug,
),
),
);
$loop = new WP_Query($args);
if($loop->have_posts()) :
$product_coming_soon_image = get_field( 'product_coming_soon_image' );
while($loop->have_posts()) : $loop->the_post();
if(!in_array( $post->ID, $displayed_products )) :
$termsArray = get_the_terms( $post->ID, "product_category" );
$termsString = "";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug.' ';
} ?>
<div class="<?php echo $termsString; ?> isotope-item">
<a href="<?php the_permalink(); ?>">
<?php if ( has_post_thumbnail() ) : ?>
<img src="<?php the_post_thumbnail_url('') ?>" class="lazy" alt="<?php the_title() ?>" loading="lazy" width="240" height="240">
<?php else : ?>
<img src="<?php echo esc_url( $product_coming_soon_image['sizes']['our-products'] ); ?>" alt="<?php echo esc_attr( $product_coming_soon_image['alt'] ); ?>" loading="lazy" width="240" height="240" />
<?php endif; ?>
</a>
<h3><?php the_title(); ?></h3>
</div>
<?php
array_push( $displayed_products, $post->ID );
endif;
endwhile; ?>
<?php
endif;
endforeach; ?>
'''
$product_categories = get_field( 'product_filter_categories' );
$custom_taxonomy='product_category';
$custom_terms = $product_categories->term_id;
foreach($custom_terms as $custom_term) :
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'tax_query' => array(
array(
'taxonomy' => $custom_taxonomy,
'field' => 'term_id',
'terms' => array($custom_terms),
'operator' => 'IN',
),
),
);
$loop = new WP_Query($args);
if($loop->have_posts()) :
$product_coming_soon_image = get_field( 'product_coming_soon_image',get_the_ID());
while($loop->have_posts()) : $loop->the_post();
$termsArray = get_the_terms( get_the_ID(), "product_category" );
$termsString = "";
foreach ( $termsArray as $term ) {
$termsString .= $term->slug.' ';
} ?>
<div class="<?php echo $termsString; ?> isotope-item">
<a href="<?php get_permalink(); ?>">
<?php if ( has_post_thumbnail() ) : ?>
<img src="<?php the_post_thumbnail_url('') ?>" class="lazy" alt="<?php get_the_title() ?>" loading="lazy" width="240" height="240">
<?php else : ?>
<img src="<?php echo esc_url( $product_coming_soon_image['sizes']['our-products'] ); ?>" alt="<?php echo esc_attr( $product_coming_soon_image['alt'] ); ?>" loading="lazy" width="240" height="240" />
<?php endif; ?>
</a>
<h3><?php get_the_title(); ?></h3>
</div>
<?php
endwhile; wp_reset_query();?>
<?php
endif;
endforeach; ?>
</div>

How to add pagination to a custom Word Press loop?

This is my code here -
<div class="gallery-posts">
<?php
$args = array(
'post_type' => 'post',
'order' => 'ASC',
'numberposts' => 4
);
$product_posts = get_posts( $args );
?>
<?php foreach ( $product_posts as $post ) : setup_postdata( $post ); ?>
<?php $videos = rwmb_meta( '_video-link' );
foreach ( $videos as $video ); ?>
<div
class="card-container video-link"
data-link="<?php echo $video['src']; ?>"
title="<?php the_title(); ?>"
description="<?php echo ( get_post_meta( get_the_ID(), '_description', true ) ); ?>"
thumbnail-link="<?php the_post_thumbnail_url() ?>">
<figure class="gallery-image">
<?php the_post_thumbnail(); ?>
<div class="gallery-image-text">
<p><?php the_title() ?></p>
<i class="fas fa-play"></i>
</div>
</figure>
</div>
<?php endforeach; wp_reset_postdata(); ?>
</div>
I want to set it up so that Next/Prev shows whenever there are more than 4 posts.
With the regular Word Press loop I know you can just do the_posts_pagination but that doesn't work here.
What needs to be added for pagination to work with this loop?
Change your code like this:
<div class="gallery-posts">
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'order' => 'ASC',
'posts_per_page' => 4,
'paged' => $paged
);
$product_posts = get_posts( $args );
foreach ( $product_posts as $post ) : setup_postdata( $post );
$videos = rwmb_meta( '_video-link' );
foreach ( $videos as $video ):
?>
<div class="card-container video-link" data-link="<?php echo $video['src']; ?>" title="<?php the_title(); ?>" description="<?php echo ( get_post_meta( get_the_ID(), '_description', true ) ); ?>" thumbnail-link="<?php the_post_thumbnail_url() ?>">
<figure class="gallery-image">
<?php the_post_thumbnail(); ?>
<div class="gallery-image-text">
<p><?php the_title() ?></p>
<i class="fas fa-play"></i>
</div>
</figure>
</div>
<?php
next_posts_link( 'Older Entries', $product_posts->max_num_pages );
previous_posts_link( 'Next Entries »' );
wp_reset_postdata();
endforeach;
?>
</div>

Exclude specific Woocommerce product category term(s) from a WP Query

I'm trying to load latest product in Woocommerce (on home page). I want to exclude specific product category from display on the loop, but exclude product category id is not working for me.
What I have done so far:
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'post_status' => 'publish',
'taxonomy' => 'product_cat',
'exclude' => 29,//exclude mention category id from loop
'parent' => 0
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
?>
<div class="popular-inner">
<a href="<?php echo get_permalink(); ?>">
<div class="popular-image d-flex ">
<div class="align-self-center mx-auto ">
<?php the_post_thumbnail(); ?>
</div>
</div>
<div class="popular-content-wp">
<div class="popular-title">
<h6><?php echo get_the_title(); ?></h6>
</div>
<div class="popular-price">
<p><?php echo wc_price($product->get_price()); ?></p>
</div>
<div class="popular-add-to-cart">
<ul>
<li>
Add to Cart
</li>
</ul>
</div>
</div>
</a>
</div>
<?php endwhile; wp_reset_query();?>
Since wordpress version 3.1 using a taxonomy slug in a WP_Query is deprecated in flavor of tax_query. Also there are some other mistakes. See WP_Query taxonomy parameters.
Your revisited code:
<?php
$loop = new WP_Query( array(
'post_type' => 'product',
'posts_per_page' => 12,
'post_status' => 'publish',
'parent' => 0,
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => array( 29 ), // Term ids to be excluded
'operator' => 'NOT IN' // Excluding terms
) ),
) );
if ( $loop->have_posts() ) :
while ( $loop->have_posts() ) : $loop->the_post();
// Get the instance of the WC_Product from the post ID
$product = wc_get_product( get_the_id() );
?>
<div class="popular-inner">
<a href="<?php echo get_permalink(); ?>">
<div class="popular-image d-flex ">
<div class="align-self-center mx-auto ">
<?php the_post_thumbnail(); ?>
</div>
</div>
<div class="popular-content-wp">
<div class="popular-title">
<h6><?php echo get_the_title(); ?></h6>
</div>
<div class="popular-price">
<p><?php echo wc_price( $product->get_price() ); ?></p>
</div>
<div class="popular-add-to-cart">
<ul>
<li>
Add to Cart
</li>
</ul>
</div>
</div>
</a>
</div>
<?php
endwhile;
wp_reset_postdata();
else: ?>
<p><?php _e( 'No posts found.' ); ?></p>
<?php endif;
?>
It should work now.

">" close php tags in wordpress

I have a problems using wordpress. I'm editing wordpress page online and using array in it, so when I wrote this on my page,
<section id="recent">
<h1>Recently Added</h1>
<ul class="row-fluid">
<?php
$args = array( 'post_type' => 'product', 'stock' => 1, 'posts_per_page' => 4, 'orderby' =>'date','order' => 'DESC' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<li class="span3">
<a id="id-<?php the_id(); ?>" href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
<?php if (has_post_thumbnail( $loop->post->ID )) echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog'); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="65px" height="115px" />'; ?>
<h3><?php the_title(); ?></h3>
<span class="price"><?php echo $product->get_price_html(); ?></span>
</a>
<?php woocommerce_template_loop_add_to_cart( $loop->post, $product ); ?>
</li><!-- /span3 -->
<?php endwhile; ?>
<?php wp_reset_query(); ?>
</ul><!-- /row-fluid -->
</section><!-- /recent -->
The result, is the page is showing this instead what I wished for,
‘product’, ‘stock’ => 1, ‘posts_per_page’ => 4, ‘orderby’
=>’date’,’order’ => ‘DESC’ ); $loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?> ‘; ?>
get_price_html(); ?>
post, $product ); ?>
Please help me understand what is happening, and how to solve it.
At least I know that in this part of the codes,
$args = array( 'post_type' => 'product', 'stock' => 1, 'posts_per_page' => 4, 'orderby' =>'date','order' => 'DESC' );
The first '>' symbol, close the php tag
I think you should use curly braces for the if/else clause in this line:
<?php if (has_post_thumbnail( $loop->post->ID )) { echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog'); } else { echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="65px" height="115px" />'; } ?>

WooCommerce - add link to product in loop

I feel like this should be very simple but I've been searching for 15 mins and can't find it anywhere:
I have a loop that lists products in a certain category, and I need to modify it so that the picture and title are a link to the individual product page. Something like this is what I'm looking for.
<a href="<?php echo woocommerce_get_the_permalink() ?>">
This is what I have:
<?php
$args = array( 'post_type' => 'product', 'posts_per_page' => 4, 'product_cat' => 'power-chairs', 'orderby' => 'ID' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<div class="product">
<div class="padding">
<?php if (has_post_thumbnail( $loop->post->ID )) echo get_the_post_thumbnail($loop->post->ID); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder"/>'; ?>
<p class="caption"><?php the_title(); ?></p>
</div><!-- padding -->
</div><!-- product -->
<?php endwhile; ?>
Edit: Found it - it was href="get_permalink($product_id)"
Have you tried adding the a href link around the image and the title:
<?php
$args = array( 'post_type' => 'product', 'posts_per_page' => 4, 'product_cat' => 'power-chairs', 'orderby' => 'ID' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<div class="product">
<div class="padding">
<a href="<?php echo woocommerce_get_the_permalink() ?>">
<?php if (has_post_thumbnail( $loop->post->ID )) echo get_the_post_thumbnail($loop->post->ID); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder"/>'; ?></a>
<p class="caption"><?php the_title(); ?></p>
</div><!-- padding -->
</div><!-- product -->

Categories