woocommerce shortcode with stock quantity - php

I would like a shortcode like the following example that shows the stock of the products:
[products limit="8" columns="4" category="pantalones" cat_operator="IN"]
I would need something like this:
[products limit="8" columns="4" category="pantalones" cat_operator="IN" showstock="yes"]
I found this code a few days ago, I found it here on stackoverflow, but now I don't remember the link, sorry.:
add_shortcode( 'minimum_stock', 'minimum_stock_shortcode' );
function minimum_stock_shortcode( $atts ) {
global $woocommerce_loop;
// Attributes
$atts = shortcode_atts(
array(
'limit' => '40',
'columns' => '5',
'orderby' => 'title',
'order' => 'asc',
'category' => '',
'cat_operator' => 'IN',
'stock' => '',
),
$atts, 'minimum_stock'
);
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $atts['limit'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'meta_query' => array(
array(
'key' => '_stock',
'value' => $atts['stock'],
'compare' => '>='
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $atts['columns'];
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
This code works perfect, but not show stock in homepage
I think the solution is not to modify the shortcode, but to modify the template that it uses to visualize data, but I don't know how to do it, if someone knows where it is or how it's done, I deeply appreciate it
Very thanks for your time.

I found, solution, thanks, very thanks
add_action( 'woocommerce_after_shop_loop_item', 'bbloomer_show_stock_shop', 10 );
function bbloomer_show_stock_shop() {
global $product;
echo wc_get_stock_html( $product );
}

Related

Woocommerce product shortcode with offset attribute

I've worked with a code extracted from an old question (Woocommerce Products Offset Shortcode), so I created a new shortcode to display products with offset but I think the "orderby" and "column" parameters are not working properly.
//Shortcode for Offset Products
function products_offset_func( $atts ) {
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc',
'offset' => 0,
'category' => '', // Slugs
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), (array) $atts );
ob_start();
$query_args = array(
'columns' => $atts['columns'],
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'offset' => $atts['offset'],
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => WC()->query->get_meta_query(),
);
if( ! empty( $atts['category'] ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => trim( $atts['category'] ),
'operator' => $atts['operator']
),
);
}
?>
<ul class="products">
<?php
$loop = new WP_Query( $query_args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
<?php
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'products_offset', 'products_offset_func' );
I've tried a lot of things but nothing worked fine for me :/
I would appreciate any help or code improvements!

Woocommerce Products Offset Shortcode

I'm trying to create a custom Woocommerce products shortcode that allows me to offset a certain number of products when adding the shortcode to a page. I've been able to get the offset part working by looking at WooCommerce - Recent Products Offset and https://ericwijaya.com/load-woocommerce-loop-custom-arguments/
The problem I am having is that the Woocommerce products "category" attribute doesn't work with my new shortcode. My shorcode looks like this: [products_offset limit="8" category="fiction" offset="10" orderby="menu_order"]
Instead of displaying products using the specified category slug (in this case "fiction"), it displays all products across all categories.
This is the code I've added to my function.php:
function products_offset_func( $atts ) {
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc',
'offset' => 0,
'category' => '', // Slugs
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), (array) $atts );
ob_start();
$query_args = array(
'columns' => $atts['columns'],
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'offset' => $atts['offset'],
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => WC()->query->get_meta_query(),
);
?>
<ul class="products">
<?php
$loop = new WP_Query( $query_args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
<?php
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'products_offset', 'products_offset_func' );`
Any help would be greatly appreciated!
Figured it out. I wasn't passing the category slug into the WP_Query. Added:
if( ! empty( $atts['category'] ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => trim( $atts['category'] ),
'operator' => $atts['operator']
),
);
}
So code all together looks like this:
//Shortcode for Offset Products
function products_offset_func( $atts ) {
$atts = shortcode_atts( array(
'per_page' => '12',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc',
'offset' => 0,
'category' => '', // Slugs
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), (array) $atts );
ob_start();
$query_args = array(
'columns' => $atts['columns'],
'posts_per_page' => $atts['per_page'],
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'offset' => $atts['offset'],
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => WC()->query->get_meta_query(),
);
if( ! empty( $atts['category'] ) ) {
$query_args['tax_query'] = array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => trim( $atts['category'] ),
'operator' => $atts['operator']
),
);
}
?>
<ul class="products">
<?php
$loop = new WP_Query( $query_args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
<?php
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}
add_shortcode( 'products_offset', 'products_offset_func' );

WooCommerce:Custom product template - Pagination isn't working

all products are displayed. "posts_per_page" is not working. I try to limit products to 12 by page, but it shows all products.
Looks like my code is fine, but it isn't working.
Whats wrong with my code?
Can someone enlighten me, please?
Here's my code:
<?php
$meta_query = array();
$meta_query[] = array('key' => '_visibility','value' => array('visible', 'catalog'),'compare' => 'IN');
$meta_query[] = array('key' => '_stock_status','value' => 'instock','compare' => '=');
if($min_price !='' && $max_price !=''){
$meta_query[] = array('key' => '_price','value' => array($min_price, $max_price),'compare' => 'BETWEEN','type' => 'NUMERIC');
}
if($orderbym != '')
{
$mkey = '_price';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$query_args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 10,
'paged' => $paged,
'ignore_sticky_posts' => 1,
'orderby' => $orderby,
'order' => $order,
'posts_per_page' => -1,
'meta_query' => $meta_query,
'meta_key' => $mkey,
'tax_query' => array(
array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => 'bundle',
),
$product_catar
),
);
global $woocommerce_loop;
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $query_args));
$columns = '2';
$woocommerce_loop['columns'] = $columns;
ob_start();
if($products->have_posts()){
woocommerce_product_loop_start();
while ( $products->have_posts() ) {
$products->the_post();
wc_get_template_part( 'content', 'product' );
}
woocommerce_product_loop_end();
}else{
_e( 'No product matching your criteria.' );
}
woocommerce_reset_loop();
wp_reset_postdata();
echo '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
?>
What comes to my mind is that the filter is maybe overwriting the query args. See what you get by doing
var_dump(apply_filters( 'woocommerce_shortcode_products_query', $query_args)) ;
My guess is you'll get different query args

How do I get woocommerce product listing to show all products in one page?

I have the following category within a site:
http://rivetnuttool.com/site/product-category/blue-pneumatic-rivet-nut-tools/
And I want it to show all of the 7 products within the first page, and even if I have 100 products to show them in one single page.
I have tried with different solutions like adding this to my functions.php file:
add_filter( 'loop_shop_per_page', create_function( '$cols', 'return -1;' ) );
Rewriting the shortcode like the solution proposed here http://ideas.woothemes.com/forums/133476-woocommerce/suggestions/4146798-add-pagination-support-for-list-of-products-render
And several other online options, and none of them seems to work, I allways get the pagination and the limit.
The theme used in the site is Divi.
Just add the conditional check to your functions.php file:
if( isset( $_GET['showall'] ) )
{
add_filter( 'loop_shop_per_page', create_function( '$cols', 'return -1;' ) );
}
else
{
add_filter( 'loop_shop_per_page', create_function( '$cols', 'return 12;' ) );
}
loop_shop_per_page is the correct filter. If you aren't seeing any effect, then add a later priority. In my test case my parent theme was filtering loop_shop_per_page so my child theme's filter wasn't doing anything.
add_filter( 'loop_shop_per_page', 'so_31843880_show_all_products', 20 );
function so_31843880_show_all_products(){
return -1;
}
To apply the filter to only product categories you would add some conditional logic:
add_filter( 'loop_shop_per_page', 'so_show_all_products' );
function so_31843880_show_all_products($per_page){
if( is_taxonomy('product_cat') ){
$per_page = -1;
}
return $per_page;
}
I corrected and changed the custom code from the above blog post to:
function shortcode_settori( $atts ) {
global $woocommerce_loop;
extract( shortcode_atts( array(
'per_page' => '24',
'columns' => '4',
'orderby' => 'title',
'order' => 'desc',
'settore' => '', // Slugs
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
), $atts ) );
if ( ! $settore ) {
return '';
}
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $orderby, $order );
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => '999',
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'term_id', //This is optional, as it defaults to 'term_id'
'terms' => $settore,
'operator' => 'IN' // Possible values are 'IN', 'NOT IN', 'AND'.
)
)
);
$products = new WP_Query($args);
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
if($products->max_num_pages>1){
?>
<nav class="woocommerce-pagination">
<?php
echo paginate_links( apply_filters( 'woocommerce_pagination_args', array(
'base' => esc_url( str_replace( 999999999, '%#%', remove_query_arg( 'add-to-cart', get_pagenum_link( 999999999, false ) ) ) ),
'format' => '',
'current' => max( 1, get_query_var( 'paged' ) ),
'total' => $products->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
) ) );
?>
</nav>
<?php }
woocommerce_reset_loop();
wp_reset_postdata();
echo $return;
$return = '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
// Remove ordering query arguments
WC()->query->remove_ordering_args();
return $return;
}
add_shortcode( 'prodotti_per_settore', 'shortcode_settori' );
And everything works now.
Now, in 2019, I just adjust a parameter in a Customize panel by:
Apperance>Customize>WooCommerce Options>Shop Archive sidebar layout>total products per page
Then, fill the number I want into that.

WooCommerce custom ShortCodes

I am trying to create a custom shortcode for WooCommerce, I want to display featured products from a specific catagory at the end of a post.
There is a standard shortcode:
[featured_products per_page="12" columns="4" orderby="date" order="desc"]
I want to add catagory to this, so the new shortcode will be:
[featured_category_products category="13" per_page="4" columns="4" orderby="date" order="desc"]
To get it work it's officiously necessary to create a function for it, so I found the class-wc-shortcodes.php file with all the default shortcodes.
I add a new function based on the default featured product:
public function featured_category_products( $atts ) {
global $woocommerce_loop;
extract(shortcode_atts(array(
'category' => '',
'per_page' => '4',
'columns' => '4',
'orderby' => 'date',
'order' => 'desc'
), $atts));
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => $per_page,
'orderby' => $orderby,
'order' => $order,
'meta_query' => array(
array(
'key' => '_visibility',
'value' => array('catalog', 'visible'),
'compare' => 'IN'
),
array(
'key' => '_featured',
'value' => 'yes'
)
),
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => array( esc_attr($category) ),
'field' => 'slug',
'operator' => 'IN'
)
)
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php woocommerce_get_template_part( 'content', 'product' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
I added the category variable extraction (and checked if it worked) and added tax-query part (found it from another function that show product based on categories). So I thought this should work, but off course not. I don't get any results nor a error.
Anybody an idea how the get this to work?
If you're only looking for one product category, use 'terms' => $category. Or you can do an explode() to split a comma separated string into an array.
See Wp Query : Taxonomy Parameters.
Other notes:
Don't touch the plugin files, your changes will be lost in the next update.
Create your own plugin.
Copy the function you created to it.
Register the shortcode to make it available (using your custom function as callback):
add_shortcode( 'featured_category_product', 'featured_category_product_function' );

Categories