Lcapitao
Lcapitao

Reputation: 303

Display products attribute labels and values in WooCommerce archives pages

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) . ':&nbsp;&nbsp;</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) . ':&nbsp;&nbsp;</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) . ':&nbsp;&nbsp;</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) . ':&nbsp;&nbsp;</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)) . ':&nbsp;&nbsp;</span>';
                        echo '<div style="color: #959595;">' . $terms . '</div>';
                    ?></div><?php
                }
            }
	    ?></div><?php
    }

Upvotes: 2

Views: 4259

Answers (2)

Ashar Zafar
Ashar Zafar

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

LoicTheAztec
LoicTheAztec

Reputation: 254473

Update

The following code will:

  • Compact your code
  • Display the attribute name + values pairs automatically (without defining them).
  • specifically for product variation it will display only selected attribute values.

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.':&nbsp;&nbsp;</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

Related Questions