0

I would like to add a local product attribute value that will have a link which points to a particular 'href' value. I followed this blog and tried to add via the markup option mentioned at the end of the blog, the value turns into an anchor tag link but the href value is not taken properly. https://nicolamustone.blog/2016/03/11/make-product-attributes-linkable/

I added this snippet from the blog in my functions.php

/**
 * Register term fields
 */
add_action( 'init', 'register_attributes_url_meta' );
function register_attributes_url_meta() {
        $attributes = wc_get_attribute_taxonomies();

        foreach ( $attributes as $tax ) {
            $name = wc_attribute_taxonomy_name( $tax->attribute_name );

            add_action( $name . '_add_form_fields', 'add_attribute_url_meta_field' );
            add_action( $name . '_edit_form_fields', 'edit_attribute_url_meta_field', 10 );
            add_action( 'edit_' . $name, 'save_attribute_url' );
            add_action( 'create_' . $name, 'save_attribute_url' );
        }
}

/**
 * Add term fields form
 */
function add_attribute_url_meta_field() {

    wp_nonce_field( basename( __FILE__ ), 'attrbute_url_meta_nonce' );
    ?>

    <div class="form-field">
        <label for="attribute_url"><?php _e( 'URL', 'domain' ); ?></label>
        <input type="url" name="attribute_url" id="attribute_url" value="" />
    </div>
    <?php
}

/**
 * Edit term fields form
 */
function edit_attribute_url_meta_field( $term ) {

    $url = get_term_meta( $term->term_id, 'attribute_url', true );
    wp_nonce_field( basename( __FILE__ ), 'attrbute_url_meta_nonce' );
    ?>
    <tr class="form-field">
        <th scope="row" valign="top"><label for="attribute_url"><?php _e( 'URL', 'domain' ); ?></label></th>
        <td>
            <input type="url" name="attribute_url" id="attribute_url" value="<?php echo esc_url( $url ); ?>" />
        </td>
    </tr>
    <?php
}

/**
 * Save term fields
 */
function save_attribute_url( $term_id ) {
    if ( ! isset( $_POST['attribute_url'] ) || ! wp_verify_nonce( $_POST['attrbute_url_meta_nonce'], basename( __FILE__ ) ) ) {
        return;
    }

    $old_url = get_term_meta( $term_id, 'attribute_url', true );
    $new_url = esc_url( $_POST['attribute_url'] );


    if ( ! empty( $old_url ) && $new_url === '' ) {
        delete_term_meta( $term_id, 'attribute_url' );
    } else if ( $old_url !== $new_url ) {
        update_term_meta( $term_id, 'attribute_url', $new_url, $old_url );
    }
}

/**
 * Show term URL
 */
add_filter( 'woocommerce_attribute', 'make_product_atts_linkable', 10, 3 );
function make_product_atts_linkable( $text, $attribute, $values ) {
    $new_values = array();
    foreach ( $values as $value ) {

        if ( $attribute['is_taxonomy'] ) {
            $term = get_term_by( 'name', $value, $attribute['name'] );
            $url = get_term_meta( $term->term_id, 'attribute_url', true );

            if ( ! empty( $url ) ) {
                $val = '<a href="' . esc_url( $url ) . '" title="' . esc_attr( $value ) . '">' . $value . '</a>';
                array_push( $new_values, $val );
            } else {
                array_push( $new_values, $value );
            }
        } else {
            $matched = preg_match_all( "/\[([^\]]+)\]\(([^)]+)\)/", $value, $matches );

            if ( $matched && count( $matches ) == 3 ) {
                $val = '<a href="' . esc_url( $matches[2][0] ) . '" title="' . esc_attr( $matches[1][0] ) . '">' . sanitize_text_field( $matches[1][0] ) . '</a>';
                array_push( $new_values, $val );
            } else {
                array_push( $new_values, $value );
            }
        }
    }

    $text = implode( ', ', $new_values );

    return $text;
}

I added the cutom attribute value as : [Displayed text](https://expected-display-url.com)

What I expected it to output:

<a href="https://expected-display-url.com">Displayed text</a> 

But what it converted instead:

<a title="Displayed text">Displayed text</a> 

Even when I tried to add a specific title value like: [Displayed text](https://expected-display-url.com "title")

It always rendered as: <a title="Displayed text">Displayed text</a>

1 Answer 1

1

With the current WooCommerce release, try this instead of the make_product_atts_linkable() function in the question:

function make_product_atts_linkable( $text, $attribute, $values ) {
    $vals = array();

    if ( $attribute->is_taxonomy() ) {
        foreach ( $attribute->get_options() as $i => $id ) {
            if ( $url = get_term_meta( $id, 'attribute_url', true ) ) {
                $vals[] = '<a href="' . esc_url( $url ) . '">' . esc_html( get_term_field( 'name', $id ) ) . '</a>';
            } else {
                $vals[] = $values[ $i ];
            }
        }
    } else {
        foreach ( $attribute->get_options() as $value ) {
            $vals[] = preg_replace_callback( '/\[([^\]]+)\]\(([^) ]+)(?: "([^"]+)"|)\)/', function ( $matches ) {
                $title = ( ! empty( $matches[3] ) ) ? ' title="' . esc_attr( $matches[3] ) . '"' : '';
                return '<a href="' . esc_url( $matches[2] ) . '"' . $title . '>' . esc_html( $matches[1] ) . '</a>';
            }, $value );
        }
    }

    return wpautop( wptexturize( implode( ', ', $vals ) ) );
    //return implode( ', ', $vals ); // Use this or the above. Up to you..
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.