Reputation: 784
In WooCommerce, I would like to create a function which outputs a simple "list" of data, for each variation or a variable product. Or, if a simple product, then the details of that product itself. The details I need to include for each are: regular price
, size attribute
(used for the variations) sale price
, stock
.
This is for a "catalog" version of WooCommerce product pages, so there will be no actual Add To Cart button or Variation dropdown. Instead, I want to present the information of each product/variation to the user.
I need to output the data of each, as list items within a <ul>
. A new <ul>
for each variation.
Example of a product with 3 variations:
<div class="fs-product-data-wrapper">
<ul>
<li class="fs-data-price">$49.98 ea.</li>
<li class="fs-data-size">Size: 15-18"</li>
<li class="fs-data-sale">$49.98 ea. Preferred Customer Price</li>
<li class="fs-data-stock">Quantity in Stock: 40</li>
</ul>
<ul>
<li class="fs-data-price">$799.98 ea.</li>
<li class="fs-data-size">Size: 2-2.5'</li>
<li class="fs-data-sale">$67.98 ea. Preferred Customer Price</li>
<li class="fs-data-stock">Quantity in Stock: 15</li>
</ul>
<ul>
<li class="fs-data-price">$29.98 ea.</li>
<li class="fs-data-size">Size: 12"</li>
<li class="fs-data-sale">$19.98 ea. Preferred Customer Price</li>
<li class="fs-data-stock">Quantity in Stock: 0</li>
</ul>
</div>
Example of a product with no variations, but is just a simple product:
<div class="fs-product-data-wrapper">
<ul>
<li class="fs-data-price">$99.98 ea.</li>
<li class="fs-data-size">Size: 15-18"</li>
<li class="fs-data-sale">$99.98 ea. Preferred Customer Price</li>
<li class="fs-data-stock">Quantity in Stock: 32</li>
</ul>
</div>
Screenshot of example:
I can manage the CSS of it. I just need the ability to produce this data within a ul
for each "option". Ideally this would be done via shortcode too, since I will be populating it via a page builder template. But I could make due if it hooks into an existing product page hook. Perhaps woocommerce_after_single_product
.
Upvotes: 4
Views: 1424
Reputation: 254448
Here is a way to display some specific formatted product data for simple and variable products:
// Utility funtion: getting and formtting product data
function format_product_data_output( $the_id ){
$empty = __( '<em>(empty)</em>', 'woocommerce' );
// Get an instance of the WC_Product_Variation object
$product = wc_get_product( $the_id );
// Only wc_get_price_to_display() respect if product is to be displayed with or without including taxes
$price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ) );
$sale_price = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
$sale_price = ! empty( $sale_price ) ? wc_price($sale_price) : $empty;
$size = $product->get_attribute( 'pa_size' );
$size = ! empty( $size ) ? get_term_by( 'slug', $size, 'pa_size' )->name : $empty;
$stock_qty = $product->get_stock_quantity();
$stock_qty = ! empty( $stock_qty ) ? $stock_qty : $empty;
$output = '
<ul>
<li class="fs-data-price">'.$price.'</li>
<li class="fs-data-size">Size: '.$size.'</li>
<li class="fs-data-sale">'.$sale_price.' Preferred Customer Price</li>
<li class="fs-data-stock">Quantity in Stock: '.$stock_qty.'</li>
</ul>';
return $output;
}
//
add_action( 'woocommerce_after_single_product', 'custom_table_after_single_product' );
function custom_table_after_single_product(){
global $product;
$output = '<div class="fs-product-data-wrapper">';
// Variable products
if( $product->is_type('variable'))
{
// Get available variations in the variable product
$available_variations = $product->get_available_variations();
if( count($available_variations) > 0 ){
foreach( $available_variations as $variation )
$output .= format_product_data_output( $variation['variation_id'] );
}
}
// Simple products
elseif( $product->is_type('simple'))
{
$output .= format_product_data_output( $product->get_id() );
}
else return; // Exit
echo $output .= '</div>'; // Display
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
You will have to manage CSS (and may be some little details). Anything needed is mostly there.
Upvotes: 1
Reputation: 710
If you set size attribute like on my screen
And then create simple or variable product with attribute size, than you can add code to functions.php file of your active child theme (or active theme)
/**
* Display list data after single product
*/
function display_list_after_single_product() {
$product_data = get_product_data();
?>
<div class="fs-product-data-wrapper">
<?php
if ( isset( $product_data['price'] ) ) {
?>
<ul>
<?php
?>
<li class="fs-data-price"><?php echo $product_data['price'] ?></li>
<li class="fs-data-size"><?php echo $product_data['size'] ?></li>
<li class="fs-data-sale"><?php echo $product_data['sale_price'] ?></li>
<li class="fs-data-stock"><?php echo $product_data['stock'] ?></li>
</ul>
<?php
} else {
foreach ( $product_data as $data ) {
?>
<ul>
<?php
?>
<li class="fs-data-price"><?php echo $data['price'] ?></li>
<li class="fs-data-size"><?php echo $data['size'] ?></li>
<li class="fs-data-sale"><?php echo $data['sale_price'] ?></li>
<li class="fs-data-stock"><?php echo $data['stock'] ?></li>
</ul>
<?php
}
}
?>
</div>
<?php
}
add_action( 'woocommerce_after_single_product', 'display_list_after_single_product' );
/**
* Collect product data depending on product type
*
* @return array $product_arr
*/
function get_product_data() {
global $product;
if( $product->is_type( 'variable' ) ) {
$variation_arr = [];
$imp_variations = $product->get_available_variations();
foreach ( $imp_variations as $key => $prod_var_arr ) {
$variation_obj = new WC_Product_variation($prod_var_arr["variation_id"]);
// collect reqired variation data to array
$product_arr[] = [
'price' => $variation_obj->get_regular_price(),
'sale_price' => $variation_obj->get_sale_price(),
'size' => $prod_var_arr['attributes']['attribute_pa_size'],
'stock' => $variation_obj->get_stock_quantity(),
];
}
} else if( $product->is_type( 'simple' ) ) {
$terms = $product->get_attributes()["pa_size"]->get_terms();
$product_arr = [
'price' => $product->get_regular_price(),
'sale_price' => $product->get_sale_price(),
'size' => $terms[0]->name,
'stock' => $product->get_stock_quantity(),
];
}
return $product_arr;
}
And you will get list below of product page exactly like you asking about.
Upvotes: 1