WooCommerce: Display product variations inside of loop - php

How can I display the product variations for each product within a loop such as the one on the Shop page? Is there any function that I can add to the content-product template that retrieves the list of variations and displays them?

You can use this code to add product variation to the shop/product category loops
// Load our function when hook is set
add_action( 'pre_get_posts', 'custom_modify_query_get_posts_by_date' );
// Modify the current query
function custom_modify_query_get_posts_by_date( $query ) {
// Check if on frontend and main query is modified and if its shop or product category loop
if( (! is_admin() && $query->is_main_query()) && ( is_shop() || is_product_category() ) ) {
$query->set( 'order', 'ASC' );
add_filter( 'posts_where', 'rc_filter_where' );
}
return $query;
}
// Add products variation post type to the loop
function rc_filter_where( $where = '' ) {
$type = 'product_variation';
$where .= " OR post_type = '$type'";
return $where;
}

Best way to do this is alter the loop. Something like that will help:
function filter_wc_query($query_args){
if(is_archive()){ //here you can use any conditional function to show variations on
$query_args[] = ['post_parent'=> '*'];
}
return $query_args;
}
add_filter('woocommerce_get_query_vars','filter_wc_query');
Or if you want to this on view level:
https://gist.github.com/lukecav/2470d9fe6337e13da4faae2f6d5fe15f
In this solution image you can grab by standard WP function:
get_post_thumbnail($product->ID,'shop_list');
But remeber that variation link will bring user to parent product and force him to select variation once more.

Related

Adding css class to featured products in woocommerce

I would like to loop throught all products in shop/category page and add special css class to product if it is featured. I have tried to do this with add_filter hook but it seems I am to dumb to get it working.
You were right about using a filter. I don't know which filter you were trying but you would edit the post_class and add a class if the post type is a product and has the specific category you want.
add_filter( 'post_class', 'namespace_featured_posts' );
function namespace_featured_posts( $classes ) {
if( 'product' == get_post_type() && has_term( 'featured', 'product_cat') ) {
$classes[] = 'featured-post';
return $classes;
}
}

How to exclude a specific category from blog posts

How to exclude a specific category from blog posts in WordPress but if a blog post has two categories selected, one from excluded category and the other from included I would like to show the blog post.
function exclude_category_home( $query ) {
if ( $query->is_home ) {
$query->set( 'cat', '-7' );
}
return $query;
}
add_filter( 'pre_get_posts', 'exclude_category_home' );
I tried using this function in function.php, it hides the excluded category but when two categories are selected for one blog post, it still hides
/* you may try this code and use category__not_in function */
function exclude_posts_from_home_page( $query )
{
if( $query->is_home() )
{
$query->set( 'category__not_in', array( 7 ) ); // here array of all category ids
}
}
add_action( 'pre_get_posts', 'exclude_posts_from_home_page' );

WooCommerce - Hide products with same title

I need to hide products with same title from shop page.
I have many products with different SKU but same name.
Is it possible to achieve that with a distinct function like this or should i create a custom loop?
add_filter( 'posts_distinct', function ( $distinct ) {
//if same name update_post_meta( $product_id, '_visibility', '_visibility_search' );
return 'DISTINCT'; });
Ok so i've found the solution by using a function, in case anyone in the future needs it.
add_filter( 'posts_groupby', 'custom_posts_groupby', 10, 2 );
function custom_posts_groupby( $groupby, $query ) {
global $wpdb;
if ( is_main_query() && (is_shop() || is_product_category() || is_search() )) {
$groupby = "{$wpdb->posts}.post_title";
}
return $groupby;
}

How to add post tags to WooCommerce products?

I noticed that post tags are different than WooCommerce product tags.
I need to add post tags to WooCommerce products so i can include some WooCommerce products in the post tag archives.
Is this possible?
I've tried these code snippets but it doesn't add them.
add_filter( 'pre_get_posts', 'add_custom_types' );
function add_custom_types( $query ) {
if ( is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
$query->set( 'post_type', array( 'post', 'products', 'product' ) );
return $query;
}
}
add_filter('request', 'post_type_tags_fix');
function post_type_tags_fix($request) {
if ( isset($request['tag']) && !isset($request['post_type']) )
$request['post_type'] = array( 'products', 'product' );
return $request;
}
I needed to do this as well and have come up with what I think is a good way of doing this. A few steps:
Firstly, you need to add the post_tag taxonomy to the woocommerce product post type. You can do this easily with the following filter:
function custom_wc_add_post_tags( $args ){
$args['taxonomies'] = array('post_tag');
return $args;
}
add_filter( 'woocommerce_register_post_type_product', 'custom_wc_add_post_tags' );
This will add a new 'Tags' item to your admin menu, and allow you to tag products with regular post tags rather that the woocommerce-specific 'product_tag' taxonomy. Secondly, you'll likely want to remove the 'product_tag' taxonomy if you don't plan on using it? Because the above will result in two admin menu items called 'tags' which will get confusing. The following will do that for you:
add_filter('woocommerce_taxonomy_objects_product_tag', '__return_empty_array');
add_filter('woocommerce_taxonomy_args_product_tag', '__return_empty_array');
And to remove the column from the 'Products' table on the backend:
function custom_wc_remove_product_tags_column($columns){
unset( $columns['product_tag'] );
return $columns;
}
add_filter( 'manage_edit-product_columns', 'custom_wc_remove_product_tags_column', 15 );
That will actually add the tags to your products. If you then need these to show up in your archive page, you may still need to modify that page's query to look for posts of type 'product' as well as the standard 'post'. It looks like your function above on the 'pre_get_posts' hook will do that part for you. Hope this helps!
Use below code to get archive page in product tag page. now product tag page use theme archive.php file.
Add Below code in theme functions.php
add_filter( 'template_include', 'woocommerce_product_tag_page_template', 99 );
if ( ! function_exists( 'hcode_post_format_parameter' ) ) {
function woocommerce_product_tag_page_template( $template ) {
if ( is_tax( 'product_tag' ) ) {
get_template_part('archive');
}
return $template;
}
}

Woocommerce Admin Order Details - Show custom data on order details page

I'm searching and trying it for 2 days with no success, please help.
I want to filter woocommerce orders to add additional details from db to order details page based on product attribute but I can't find the right woocommerce action/filter hook for this task.
Here suppose I've variable $is_customized = false;
If $is_customized == true then I need to add custom data from database to orders detail page.
NOTE: I don't want to add additional meta box instead I want to change order detail table for:
Replacing the default Product image with the image stored in database
and,
Adding a div containing custom attributes below product name.
I've all these values in my variables but I can't figure out which action hook should I use.
I've attached an image for clarification.
Just need to know if I can change / filter these order results and how ?
I appreciate for your time and help.
Thanks
Here's a start on how to display some extra data on the woocommerce_before_order_itemmeta hook:
add_action( 'woocommerce_before_order_itemmeta', 'so_32457241_before_order_itemmeta', 10, 3 );
function so_32457241_before_order_itemmeta( $item_id, $item, $_product ){
echo '<p>bacon</p>';
}
I don't know how you are saving your data, so I can't make more a more precise suggestion. Keep in mind that immediately following that hook, anything you've saved as order item meta will automatically display.
Filtering the image is more difficult. I've found this gist as a start, but it requires some custom conditional logic as you don't want to filter the thumbnail everywhere, but only in orders.
Edit: Currently the best I can do for filtering the item thumbnails:
add_filter( 'get_post_metadata', 'so_32457241_order_thumbnail', 10, 4 );
function so_32457241_order_thumbnail( $value, $post_id, $meta_key, $single ) {
// We want to pass the actual _thumbnail_id into the filter, so requires recursion
static $is_recursing = false;
// Only filter if we're not recursing and if it is a post thumbnail ID
if ( ! $is_recursing && $meta_key === '_thumbnail_id' ) {
$is_recursing = true; // prevent this conditional when get_post_thumbnail_id() is called
$value = get_post_thumbnail_id( $post_id );
$is_recursing = false;
$value = apply_filters( 'post_thumbnail_id', $value, $post_id ); // yay!
if ( ! $single ) {
$value = array( $value );
}
}
return $value;
}
add_filter( 'post_thumbnail_id', 'so_custom_order_item_thumbnail', 10, 2 );
function so_custom_order_item_thumbnail( $id, $post_id ){
if( is_admin() ){
$screen = get_current_screen();
if( $screen->base == 'post' && $screen->post_type == 'shop_order' ){
// this gets you the shop_order $post object
global $post;
// no really *good* way to check post item, but could possibly save
// some kind of array in the order meta
$id = 68;
}
}
return $id;
}

Categories