Reputation: 303
I have both simple and variable products. I also have a plugin for displaying in the shop each variation by itself and not only its parent. I have set 4 attributes, each with several possible values, and all products may share all or part of these attributes. In the future there may be more attributes and they may apply to all products or only to part.
I need to display under each variation (as well as under simple products) and under the variation parents ONLY the label and value attributes that the respective product have - and not all possible values that may apply to that attribute.
Finally one must consider that the site has more than one language with WPML.
For this purpose, I am using the following code which works but that implies repeating the same code for each attribute (you can see that I repeat the same 4x). There is surely a way to incorporate a foreach cycle to do the job. I have tried this more than once with same examples I saw in StackExchange, but to no avail.
add_action( 'woocommerce_after_shop_loop_item_title', 'add_attributes_terms', 1);
function add_attributes_terms() {
$tax_bar = 'pa_bar-colour';
$tax_but = 'pa_button-colour';
$tax_caps = 'pa_caps-colour';
$tax_cas = 'pa_lock-cases-colour';
$att_bar = get_the_terms( $product->id, $tax_bar);
$att_but = get_the_terms( $product->id, $tax_but);
$att_caps = get_the_terms( $product->id, $tax_caps);
$att_cas = get_the_terms( $product->id, $tax_cas);
?><div style="font-size: 11px; overflow: overlay; padding: 0px 5px 15px 5px; line-height: 13px;"><?php
if (! empty($att_bar)) {
?><div style="overflow: overlay;"><?php
echo '<span style=" float: left; color: #444;">' . str_replace(" colour", "", get_taxonomy($tax_bar)->labels->singular_name) . ': </span>';
?><div style="overflow: overlay; color: #959595;"><?php
if ( $att_bar && ! is_wp_error( $$att_bar )): foreach ( $att_bar as $attributes_name ){
echo '<span>' . ' ' . $attributes_name->name . ' ' . '</span>';
}
endif;
?></div><?php
?></div><?php
}
if (! empty($att_but)) {
?><div class="b2" style="overflow: overlay;"><?php
echo '<span style=" float: left; color: #444;">' . str_replace(" colour","", get_taxonomy($tax_but)->labels->singular_name) . ': </span>';
?><div style="overflow: overlay; color: #959595;"><?php
if ( $att_but && ! is_wp_error( $$att_but )): foreach ( $att_but as $attributes_name ){
echo '<span>' . ' ' . $attributes_name->name . ' ' . '</span>';
}
endif;
?></div><?php
?></div><?php
}
if (! empty($att_caps)) {
?><div style="overflow: overlay;"><?php
echo '<span style=" float: left; color: #444;">' . str_replace(" colour","", get_taxonomy($tax_caps)->labels->singular_name) . ': </span>';
?><div style="overflow: overlay; color: #959595;"><?php
if ( $att_caps && ! is_wp_error( $$att_caps )): foreach ( $att_caps as $attributes_name ){
echo '<span>' . ' ' . $attributes_name->name . ' ' . '</span>';
}
endif;
?></div><?php
?></div><?php
}
if (! empty($att_cas)) {
?><div style="overflow: overlay;"><?php
echo '<span style=" float: left; color: #444;">' . str_replace(" colour","", get_taxonomy($tax_cas)->labels->singular_name) . ': </span>';
?><div style="overflow: overlay; color: #959595;"><?php
if ( $att_cas && ! is_wp_error( $$att_cas )): foreach ( $att_cas as $attributes_name ){
echo '<span>' . ' ' . $attributes_name->name . ' ' . '</span>';
}
endif;
?></div><?php
?></div><?php
}
?></div><?php
}
How can I compact this code avoiding html bocks repetitions?
How can I get all attributes for all product types, getting for product variations only the selected attribute values?
After all the input I received, my final code already working fine:
add_action( 'woocommerce_after_shop_loop_item_title', 'add_attributes_terms', 1);
function add_attributes_terms() {
global $product;
?><div style="font-size: 10px; overflow: overlay; padding: 6px 10px 6px 10px; line-height: 13px; box-shadow: inset 0 0 5px rgba(0,0,0,0.1), inset 0 3px 2px rgba(0,0,0,0.1);"><?php
// Loop through each defined attribute
foreach( $product->get_attributes() as $taxonomy => $values ){
$terms = $product->get_attribute( $taxonomy );
if(!empty($terms)){
?><div style="overflow: overlay;"><?php
echo '<span id="shop_labels" style=" float: left; color: #444;">' . str_replace([" colour", "Cor da ", "Cor do ", "Cor das ", " de parede"], ["","","","",""], wc_attribute_label($taxonomy)) . ': </span>';
echo '<div style="color: #959595;">' . $terms . '</div>';
?></div><?php
}
}
?></div><?php
}
Upvotes: 2
Views: 4259
Reputation: 402
Code for drop down in shop page Display variations dropdowns on shop page for variable products
add_filter( 'woocommerce_loop_add_to_cart_link', 'woo_display_variation_dropdown_on_shop_page' );
function woo_display_variation_dropdown_on_shop_page() {
global $product;
if( $product->is_type( 'variable' )) {
$attribute_keys = array_keys( $product->get_attributes() );
?>
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo htmlspecialchars( json_encode( $product->get_available_variations() ) ) ?>">
<?php do_action( 'woocommerce_before_variations_form' ); ?>
<?php if ( empty( $product->get_available_variations() ) && false !== $product->get_available_variations() ) : ?>
<p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
<?php else : ?>
<table class="variations" cellspacing="0">
<tbody>
<?php foreach ( $product->get_variation_attributes() as $attribute_name => $options ) : ?>
<tr>
<td class="label"><label for="<?php echo sanitize_title( $attribute_name ); ?>"><?php echo wc_attribute_label( $attribute_name ); ?></label></td>
<td class="value">
<?php
$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( urldecode( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ) : $product->get_variation_default_attribute( $attribute_name );
wc_dropdown_variation_attribute_options( array( 'options' => $options, 'attribute' => $attribute_name, 'product' => $product, 'selected' => $selected ) );
echo end( $attribute_keys ) === $attribute_name ? apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . __( 'Clear', 'woocommerce' ) . '</a>' ) : '';
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<div class="single_variation_wrap">
<?php
/**
* woocommerce_before_single_variation Hook.
*/
do_action( 'woocommerce_before_single_variation' );
/**
* woocommerce_single_variation hook. Used to output the cart button and placeholder for variation data.
* @since 2.4.0
* @hooked woocommerce_single_variation - 10 Empty div for variation data.
* @hooked woocommerce_single_variation_add_to_cart_button - 20 Qty and cart button.
*/
do_action( 'woocommerce_single_variation' );
/**
* woocommerce_after_single_variation Hook.
*/
do_action( 'woocommerce_after_single_variation' );
?>
</div>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_after_variations_form' ); ?>
</form>
<?php } else {
echo sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() )
);
}
}
Upvotes: 0
Reputation: 254473
Update
The following code will:
The code:
add_action( 'woocommerce_after_shop_loop_item_title', 'shop_loop_display_product_attributes', 4);
function shop_loop_display_product_attributes() {
global $product;
$attributes = array();
echo '<div style="font-size: 11px; overflow: overlay; padding: 0px 5px 15px 5px; line-height: 13px;">';
// Loop through each defined attribute
foreach ( $product->get_attributes() as $taxonomy => $values ) {
$term_names = array();
// Get the class for only 'pa_button-colour' case
$class = $taxonomy == 'pa_button-colour' ? ' class="b2"' : '';
$taxonomy_label = get_taxonomy($taxonomy)->labels->singular_name;
$label_name = str_replace(" colour", "", $taxonomy_label );
echo '<div'. $class .' style="overflow: overlay;">
<span style=" float: left; color: #444;">'.$label_name.': </span>';
if( $product->is_type('variation') ) // Product variation type (For your plugin)
{
$term_names[] = get_term_by( 'slug', $values, $taxonomy )->name;
}
else // Other product types
{
$term_ids = $values->get_options();
foreach ( $term_ids as $term ) {
$term_names[] = get_term( $term, $taxonomy )->name;
}
}
if ( count($term_names) != 0 ) {
echo '<div style="overflow: overlay; color: #959595;">
<span> ' . implode( ' </span><span> ', $term_names ) . ' </span>
</div>';
}
echo '</div>';
}
echo '</div>';
}
This code is tested and doesn't output any error… It should work for you.
Upvotes: 1