How do I change button text from “Choose an option” in Woocommerce?

How would I go about changing this PHP code to to change Choose an option based on the id of the select element in the Woocommerce plugin for WordPress? I believe I have found the correct PHP file in wc-template-function.php but my lack of PHP skills is holding me back. Here is what I have so far:

if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) {

    /**
     * Output a list of variation attributes for use in the cart forms.
     *
     * @param array $args
     * @since 2.4.0
     */
    function wc_dropdown_variation_attribute_options( $args = array() ) {
        $args = wp_parse_args( $args, array(
            'options'          => false,
            'attribute'        => false,
            'product'          => false,
            'selected'         => false,
            'name'             => '',
            'id'               => '',
            'class'            => '',
            'show_option_none' => __( 'Choose an option', 'woocommerce' ),
            'show_option_color' => __( 'Choose a color', 'woocommerce' ),
            'show_option_size' => __( 'Choose a size', 'woocommerce' )
        ) );

        $options   = $args['options'];
        $product   = $args['product'];
        $attribute = $args['attribute'];
        $name      = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
        $id        = $args['id'] ? $args['id'] : sanitize_title( $attribute );
        $class     = $args['class'];

        if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
            $attributes = $product->get_variation_attributes();
            $options    = $attributes[ $attribute ];
        }

        echo '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '">';

        if ( $args['show_option_none'] ) {
            echo '<option value="">' . esc_html( $args['show_option_none'] ) . '</option>';
        }
        if ( $args['$id_colors'] ) {
            echo '<option value="">' . esc_html( $args['show_option_color'] ) . '</option>';
        }
        if ( $args['$id_sizes'] ) {
            echo '<option value="">' . esc_html( $args['show_option_size'] ) . '</option>';
        }

        if ( ! empty( $options ) ) {
            if ( $product && taxonomy_exists( $attribute ) ) {
                // Get terms if this is a taxonomy - ordered. We need the names too.
                $terms = wc_get_product_terms( $product->id, $attribute, array( 'fields' => 'all' ) );

                foreach ( $terms as $term ) {
                    if ( in_array( $term->slug, $options ) ) {
                        echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . apply_filters( 'woocommerce_variation_option_name', $term->name ) . '</option>';
                    }
                }
            } else {
                foreach ( $options as $option ) {
                    // This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
                    $selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
                    echo '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
                }
            }
        }

        echo '</select>';
    }
}

You can see where I tried to add show_option_color and show_option_size in to the array and then add if statements for them, but it doesn’t seem to be working. I’m not sure how to reference the id of the select element and write the if statement based on if its is the correct select element.

Read More

Here is the HTML I’m trying to target.

<select id="sizes" class="" name="attribute_sizes" data-attribute_name="attribute_sizes">Want this to say Choose a size</select>

<select id="colors" class="" name="attribute_sizes" data-attribute_name="attribute_sizes">Want this to say Choose a color</select>

variable.php code lines 27 – 38:

<?php foreach ( $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( $_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 ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : '';
                            ?>
                        </td>
                    </tr>
                <?php endforeach;?>

Related posts

8 comments

  1. This is a perfect use case for a custom filter! I am first going to describe a method that is not the quickest way, but it is probably the cleanest and easiest to understand for anyone else who might have to read your code. I will also describe a ‘dirtier’ way that should do the job if you are in a time crunch.

    Quick Way:

    The place to find where this is displayed is in the file:

    /wp-content/plugins/woocommerce/templates/single-product/add-to-cart/variable.php
    

    Around line 27, depending on your version of WooCommerce, you will see something like this line:

    <option value=""><?php echo __( 'Choose an option', 'woocommerce' ) ?>&hellip;</option>
    

    The __() function is running the first parameter through WordPress’s translation system using the ‘woocommerce’ text domain. It is best to preserve the possibility for translation, so we will want to change this text before we send it through the translation function.

    This line of code happens during a loop that outputs all of the product variation attributes. This allows us to easily see which attribute is being output by looking at the $name variable.

    We will need to make a function that takes in the $name variable and outputs a string based on it. It would look something like this:

    function get_text_for_select_based_on_attribute($attribute) {
    
    // Find the name of the attribute for the slug we passed in to the function
    $attribute_name = wc_attribute_label($attribute);
    
    // Create a string for our select
    $select_text = 'Select a ' . $attribute_name;
    
    // Send the $select_text variable back to our calling function
    return $select_text;
    }
    

    Now, before the code on line 27 of variable.php, we can put something like this:

    <?php 
    
      $select_text = get_text_for_select_based_on_attribute($name);
    
    ?>
    

    Then, simply swap out ‘Choose an option’ with your $select_text variable:

    <option value=""><?php echo __( $select_text, 'woocommerce' ) ?>&hellip;</option>
    

    Don’t forget to do this all in a template override or your customization will be lost on the next update!

    http://docs.woothemes.com/document/template-structure/

    Cleaner Way:

    A better and more extensible way of doing this is to add a custom filter to pass this through. It’s a few extra steps, but allows you to easily add further custom logic if you want to override the functionality on a case-by-case basis depending on your product.

    First, make a custom filter with a semantically-meaningful name, and put it somewhere in your functions.php file for the theme:

    add_filter('variable_product_select_text', 'get_text_for_select_based_on_attribute', 10, 1);
    

    Then, in the variable.php file, instead of just calling the function directly, pass it through your new filter:

    $select_text = apply_filters('variable_product_select_text', $name);
    

    Setting up custom filters for things like this does take a little bit longer, but you get the advantage of maintainability, since you can stack or turn off functions down the road without needing to further modify your existing code.

    Update for WC 2.4

    Version 2.4 of WooCommerce introduces a different way of getting attributes and their associated selects. Since they still have not provided a filter for this, I would recommend overriding the wc_dropdown_variation_attribute_options function using the methods described above. So copy and paste the entire function into your theme’s functions.php file starting at the declaration, and add a variable for the select text if it’s not a color or size:

    //Don't include the if(!function_exists(...) part.
    
    wc_dropdown_variation_attribute_options($args = array()) {
      // Uses the same function as above, or optionally a custom filter
      $select_text = get_text_for_select_based_on_attribute($args['attribute']);
    
      wc_dropdown_variation_attribute_options( $args = array() ) {
        $args = wp_parse_args( $args, array(
            'options'          => false,
            'attribute'        => false,
            'product'          => false,
            'selected'         => false,
            'name'             => '',
            'id'               => '',
            'class'            => '',
            'show_option_none' => __( $select_text, 'woocommerce' ),
            'show_option_color' => __( 'Choose a color', 'woocommerce' ),
            'show_option_size' => __( 'Choose a size', 'woocommerce' )
        ) );
    // Put the rest of the function here
    
  2. I have done this using a combination of the other answers here and it worked well for me.

    This was done using WooCoommerce 3.3.5 and assume the filter was added relatively recently.

    You use the filter for the wc_dropdown_variation_attribute_options() function.

    // define the woocommerce_dropdown_variation_attribute_options_args callback 
    function filter_woocommerce_dropdown_variation_attribute_options_args( $array ) { 
    
        // Find the name of the attribute for the slug we passed in to the function
        $attribute_name = wc_attribute_label($array['attribute']);
    
        // Create a string for our select
        $select_text = 'Select a ' . $attribute_name;
    
        $array['show_option_none'] = __( $select_text, 'woocommerce' );
        return $array; 
    }; 
    
    // add the filter 
    add_filter( 'woocommerce_dropdown_variation_attribute_options_args', 'filter_woocommerce_dropdown_variation_attribute_options_args', 10, 1 ); 
    

    Hope this helps someone.

  3. I found a way with WC 2.5. Add this to functions.php:

    function my_dropdown_variation_attribute_options_html($html, $args){
        $html = str_replace('Choose an option', 'Choose', $html);
        return $html;
    }
    add_filter('woocommerce_dropdown_variation_attribute_options_html', 'my_dropdown_variation_attribute_options_html', 10, 2);
    
  4. There is actually an easier way to customize it.

    If you take a look at the core WC file wc-template-functions.php you can see that the array inside wc_dropdown_variation_attribute_options function is actually it’s arguments with the following key value pairs:

    'options'          => false,
    'attribute'        => false,
    'product'          => false,
    'selected'         => false,
    'name'             => '',
    'id'               => '',
    'class'            => '',
    'show_option_none' => __( 'Choose an option', 'woocommerce' )
    

    Now all you need to do is to change the same key value pair in the function in variable.php template file. So I wanted to show the dropdown label instead of the Choose An Option text so I change the fu

    wc_dropdown_variation_attribute_options(
        array(
             'options' => $options,
             'attribute' => $attribute_name,
             'product' => $product,
             'selected' => $selected,
             'show_option_none' => wc_attribute_label( $attribute_name )
        )
    );
    

    Same goes with other pairs. Hoep this helps. By the way, this only works in WC 2.4+ so be careful.

  5. Here’s a pretty simple solution for WC >2.4 that avoids rewriting functions and cluttering up your functions.php..

    Add the variable.php file to your theme (http://docs.woothemes.com/document/template-structure/), and change this (from line 27):

    <?php foreach ( $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( $_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 ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : '';
            ?>
        </td>
    </tr><?php endforeach;?>
    

    to this:

    <?php 
    $variations_arr = array();
    foreach ( $attributes as $attribute_name => $options ) : 
        ob_start(); ?>
        <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( $_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 ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : ''; ?>
            </td>
        </tr>
        <?php $variations_ob = ob_get_clean();
        $variations_arr[wc_attribute_label($attribute_name)] = $variations_ob;
    endforeach;
    
    foreach ($variations_arr as $name => $ob) {
        echo str_ireplace('choose an option', 'Choose '.$name, $ob );
    } ?>
    

    This will replace ‘Choose an option’ with ‘Choose Size’, ‘Choose Colour’ etc. depending on the name of your attribute.

  6. If you’re looking to change dropdown text from “Choose an option” in Woocommerce, add following to functions.php file in your theme:

    add_filter('woocommerce_dropdown_variation_attribute_options_args', 'my_change_choose_an_option_text_func', 10, 2);
    
    function my_change_choose_an_option_text_func($args){ 
        $args['show_option_none'] = __( 'New Text', 'your_text_domain' ); 
        return $args; 
    }
    
  7. If you are wondering how to replace “Choose an option” with corresponding attribute/variation name, then here’s how you can do that.
    edit variable.php and lookout for the code as the one shown below

    Open the variable.php(wp-content/plugins/woocommerce/includes/variable.php) file to your woocommerce and change this (from line 41 to 43): (Remove this 3 line code)

    $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>' ) : '';
    

    Then add this code

    wc_dropdown_variation_attribute_options
    array( 'options' => $options,
    'attribute' => $attribute_name,
    'product' => $product,
    'selected' => $selected,
    'show_option_none'=> wc_attribute_label( $attribute_name )
    ) );
    

    It’s working all WordPress version
    Thanks

  8. Updated code, made it for anyone still interested

    add_filter( 'woocommerce_dropdown_variation_attribute_options_args', 
    fix_option', 10 ); 
    function fix_option( $args ) {
        $attr = get_taxonomy( $args['attribute'] ); 
        $label = $attr->labels->name; 
        $fix = str_replace('Product', '', $label); 
        $fix = strtolower($fix); /
        $args['show_option_none'] = apply_filters( 'the_title', 'Select a '.$fix ); 
    }
    

Comments are closed.