Okay so I'm trying to create dynamic product filters that display certain product attributes for certain categories. The attributes that are displayed are chosen via checkbox on the "Edit Category" page.
I have a majority of the coding done, but I'm stuck on this one part. How do I leverage WooCommerce Layered-Nav or WordPress AJAX to turn this form and checkboxes into active product filters?
$ischecked is the array that contains the desired attributes to filter by. The WP_Query grabs all active values for our checked attributes.
<?php
echo '<form action="https://monroedirect.com/mrohardware/product-category/knobs/" method="GET">';
foreach ($ischecked as $display_attribute) {
$tax_val = str_replace(' ', '-', preg_replace('/[^\p{L}\p{N}\s]/u', '', strtolower($display_attribute)));
echo '<div class="attribute_filter" data-op="OR" data-taxonomy="pa_'.$tax_val.'" data-name="'.$display_attribute.'" id="af_'.$i.'">
';
echo '<div class="af_head"><h3>'.$display_attribute.'</h3></div>';
echo '<input type="hidden" name="query_type_'.$tax_val.'" value="or">';
$output = array(); // Initializing
$products = ( new WP_Query($args) );
if ( $products->have_posts() ) {
while ( $products->have_posts() ) {
$products->the_post();
$product = wc_get_product( get_the_id() );
$product_attributes = $product->get_attributes();
$attributes = $ischecked;
foreach ( $attributes as $attribute ) {
$taxonomy = 'pa_' . $attribute;
$values = $product->get_attribute($taxonomy);
if ( ! empty($values) ) {
if($attribute == $display_attribute) {
array_push($output, $values);
}
}
}
}
}
$attrib_list = array_unique($output);
echo '<ul>';
foreach ($attrib_list as $atrib) {
$atribraw = str_replace(' ', '-', strtolower($atrib));
echo '<li>
<input data-name="'.$atrib.'" id="filter_'.$tax_val.'" name="filter_'.$tax_val.'" type="checkbox" value="'.$atrib.'">'.$atrib.'</li>';
}
echo '</ul>';
?>
<?php
echo '</div>';
$i++;
}
echo '<button>Filter Products</button>';
echo '</form>';
?>
Related
I'm looking to add the attribute data of simple products in the infobox (cart/checkout/email). I am currently doing this with the following code:
function sm_woo_cart_attributes($cart_item, $cart_item_key){
$item_data = $cart_item_key['data'];
$attributes = $item_data->get_attributes();
if ( ! $attributes ) {
return $cart_item;
}
$out = $cart_item . '<br />';
foreach ( $attributes as $attribute ) {
if ( $attribute['is_taxonomy'] ) {
// skip variations
if ( $attribute['is_variation'] ) {
continue;
}
// backwards compatibility for attributes which are registered as taxonomies
$product_id = $item_data->id;
$terms = wp_get_post_terms( $product_id, $attribute['name'], 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ($tax_object->labels->name) ) {
$tax_label = $tax_object->labels->name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
}
foreach ( $terms as $term ) {
$out .= $tax_label . ': ';
$out .= $term->name . '<br />';
}
} else {
// not a taxonomy
$out .= $attribute['name'] . ': ';
$out .= $attribute['value'] . '<br />';
}
}
echo $out;
}
add_filter( 'woocommerce_cart_item_name', 'sm_woo_cart_attributes', 10, 2 );
This lists all of the attribute data, but above the product, shown in this screenshot. Is there any way to move the attribute data under the product image?
I've been trying for about three days now to get 4 of my woocommerce product attribute slugs instead of names to display underneath the products.
So far I've been using this code that does seem to do exactly what I want except for taking the attribute name instead of the value.
/**
* Display available attributes.
*
* #return array|void
*/
function iconic_available_attributes() {
global $product;
if ( ! $product->is_type( 'variable' ) ) {
return;
}
$attributes = iconic_get_available_attributes( $product );
if ( empty( $attributes ) ) {
return;
}
foreach ( $attributes as $attribute ) {
?>
<div class="iconic-available-attributes">
<p class="iconic-available-attributes__title"><?php _e( 'Available', 'iconic' ); ?> <strong><?php echo $attribute['name']; ?></strong></p>
<ul class="iconic-available-attributes__values">
<?php foreach ( $attribute['values'] as $value ) { ?>
<li class="iconic-available-attributes__value <?php echo $value['available'] ? '' : 'iconic-available-attributes__value--unavailable'; ?>"><?php echo $value['name']; ?></li>
<?php } ?>
</ul>
</div>
<?php
}
}
/**
* Get available attributes.
*
* #param WC_Product_Variable $product
*
* #return array
*/
/**
* #snippet Display Custom Products Attributes on the Products Page
*/
function cw_woo_attribute(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$display_result = '';
foreach ( $attributes as $attribute ) {
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
$cwtax = $terms[0]->taxonomy;
$cw_object_taxonomy = get_taxonomy($cwtax);
if ( isset ($cw_object_taxonomy->labels->singular_name) ) {
$tax_label = $cw_object_taxonomy->labels->singular_name;
} elseif ( isset( $cw_object_taxonomy->label ) ) {
$tax_label = $cw_object_taxonomy->label;
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$display_result .="<span class='attribute'>" . $tax_label . "</span>";
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
array_push( $tax_terms);
}
$display_result .= implode(', ', $tax_terms);
} else {
$display_result .= $name;
$display_result .= esc_html( implode( ', ', $attribute->get_options() ) );
}
}
echo "<span class='attributeline'>" . "| " . "</span>" . $display_result;
}
add_action('woocommerce_shop_loop_item_title', 'cw_woo_attribute', 25);
I'm not a PHP coder in any way so I've been struggling to get it to work.
Here is a sample of the current situation showing the name: "plant type" instead of the value: "annual".
Looking forward to your replies so I can move on with the rest of the shop!
Can you check this existing answer?
Wordpress Woocommerce Show attributes on shop page
I just tested it on a recent Woocommerce install, and the accepted answer seems to still work fine.
See if you can get it to work by predefining which attributes you want to show like they do in that question: pa_country, pa_class etc. You can see it in the following part.
// Define you product attribute taxonomies in the array
$product_attribute_taxonomies = array( 'pa_country', 'pa_class','pa_faction', 'pa_gender' );
If you don't want to predefine the attributes, you can still get them like below (also tested). But for testing, it might be helpful to just use the predefined strings so you are sure it's working.
$attributes = $product->get_attributes();
$attrs = [];
foreach($attributes as $key => $attribute) :
$attrs[] = $key;
endforeach;
// just replace the array with attribute names with $attrs
$product_attribute_taxonomies = $attrs;
Add the following code snippet to functions.php to display a coma separated string of term names under product on shop archive.
add_filter( 'woocommerce_after_shop_loop_item_title', 'loop_display_attr', 15 );
function loop_display_attr() {
global $product;
// The attribute slug
$attribute = 'attr';
// Get attribute term names in a coma separated string
$term_names = $product->get_attribute( $attribute );
// Display a coma separted string of term names
echo '<p>' . $term_names . '</p>';
}
In WooCommerce, I'm currently building a function that will echo some product attributes in the shop page. I would like to separate these with commas if there is multiple attribute values available, but I don't know how.
My code:
add_action('woocommerce_after_shop_loop_item_title', 'TitleVariations', 10);
function TitleVariations()
{
global $product;
$colormonth = $product->get_attribute('color-month');
$finish = $product->get_attribute('finish');
$design = $product->get_attribute('design');
echo '<span class="variation-display">';
echo __($colormonth, 'woocommerce');
echo __($finish, 'woocommerce');
echo __($crossdesign, 'woocommerce');
echo '</span>';
}
Collect your values to array and then implode this array:
$values = [
__($colormonth, 'woocommerce'),
__($finish, 'woocommerce'),
__($crossdesign, 'woocommerce'),
];
// if some values returned by `__()` are empty strings,
// you can filter your array so as to remove them
$values = array_filter($values);
echo '<span class="variation-display">';
echo implode(', ', $values);
echo '</span>';
The WC_Product method get_attribute() gives a comma separated string of values when there is more than one value… You also need to check that each different attribute has at list one term…
To get the product attribute label name, yo can use wc_attribute_label() product attribute function.
1). If you want to get each product attribute with the label name and the term(s) value(s) (each different attribute in one line), you will use the following instead.
This code handle also custom product attributes:
add_action('woocommerce_after_shop_loop_item_title', 'display_loop_product_attributtes', 10);
function display_loop_product_attributtes()
{
global $product;
// Here define your product attribute names (slugs)
$attribute_names = array('color-month', 'finish', 'design');
$attributes = array(); // Initializing
// Loop Through product attributes array
foreach( $attribute_names as $attribute_name ) {
if( taxonomy_exists( 'pa_' . $attribute_name ) ) {
$attribute = 'pa_' . $attribute_name; // Custom taxonomy
} else {
$attribute = $attribute_name; // Custom attribute (not a taxonomy)
}
$values_str = $product->get_attribute($attribute);
if ( $values_str ) {
$attributes[] = '<strong>' . wc_attribute_label($attribute) . ':</strong> ' . $values_str;
}
}
// Output product attribute label / values pairs (one by line)
if( ! empty( $attributes ) ) {
echo '<span class="variation-display">' . implode( '<br>', $attributes ) . '</span>';
}
}
2). But if you want to get all your product attributes terms as a comma separated string, your code will be something like in Display specific product attributes under product title in Woocommerce archive pages.
So for your code:
add_action('woocommerce_after_shop_loop_item_title', 'display_loop_product_attributtes', 10);
function display_loop_product_attributtes()
{
global $product;
$color_month = $product->get_attribute('color-month');
$finish = $product->get_attribute('finish');
$design = $product->get_attribute('design');
$attributes = array(); // Initializing
if ( $color_month ) {
$attributes[] = $color_month;
}
if ( $finish ) {
$attributes[] = $finish;
}
if ( $design ) {
$attributes[] = $design;
}
// Output product attribute values
if( ! empty( $attributes ) ) {
echo '<span class="variation-display">' . implode( ', ', $attributes ) . '</span>';
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
I have code which (I modified and took from here Woocommerce get specific attribute value on cart page) is showing full list of containing attributes, but I would like to use only specific attribute, let's say "colour1" to generate SVG file.
<?php
$item_data = $cart_item['data'];
$attributes = $item_data->get_attributes();
foreach ( $attributes as $attribute )
{
$out ='';
$out .= $attribute['name'] . ': ';
$out .= $attribute['value'] . '<br />';
echo $out;
}
?>
just found solution:
<?php
$item_data = $cart_item['data'];
$attributes = $item_data->get_attributes();
foreach ( $attributes as $attribute )
{
if ( $attribute['name'] == 'colour1' ) {
$out ='';
$out .= $attribute['name'] . ': ';
$out .= $attribute['value'] . '<br />';
echo $out;
}
}
?>
Simple question how to display product atributes in cart woocomerce: for example color:red, not sure if there is some code to add like hook or some code to fundctions.php or it can be done through woocomerce settings, have not found any useful information online, any help is appreciated.
Just do a simple things as follows, you will get all in your cart_item -
add_filter('woocommerce_cart_item_name', 'add_variations_in_cart', 10, 3);
function add_variations_in_cart($name, $cart_item, $item_key){
$product_variation = '';
if(!empty($cart_item['variation_id']) && $cart_item['variation_id'] != 0 ){
if(is_array($cart_item['variation']) && !empty($cart_item['variation'])){
foreach ($cart_item['variation'] as $key => $value) {
$product_variation .= '<br>'.ucfirst(str_replace('attribute_pa_', '', $key)).' : '.ucfirst($value);
}
}
}
echo $name.$product_variation;
}
as simple as that. Thank you.
tyr this plugin https://wordpress.org/plugins/woocommerce-show-attributes/
OR
WooCommerce: show all product attributes listed below each item on Cart page
add this below code in function.php
/**
* WooCommerce: show all product attributes listed below each item on Cart page
*/
function sm_woo_cart_attributes($cart_item, $cart_item_key){
$item_data = $cart_item_key['data'];
$attributes = $item_data->get_attributes();
if ( ! $attributes ) {
return $cart_item;
}
$out = $cart_item . '<br />';
foreach ( $attributes as $attribute ) {
if ( $attribute['is_taxonomy'] ) {
// skip variations
if ( $attribute['is_variation'] ) {
continue;
}
// backwards compatibility for attributes which are registered as taxonomies
$product_id = $item_data->id;
$terms = wp_get_post_terms( $product_id, $attribute['name'], 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ($tax_object->labels->name) ) {
$tax_label = $tax_object->labels->name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
}
foreach ( $terms as $term ) {
$out .= $tax_label . ': ';
$out .= $term->name . '<br />';
}
} else {
// not a taxonomy
$out .= $attribute['name'] . ': ';
$out .= $attribute['value'] . '<br />';
}
}
echo $out;
}
add_filter( 'woocommerce_cart_item_name', sm_woo_cart_attributes, 10, 2 );