HTML markup in attribute values
-
Because of a sync with a ERP system we have custom attributes (e.g. safety_regulations) with html markup and no other way to display them than in this custom attributes because of the ERP limitations. I am trying for hours and hours to the additional information tab display the markup as html output without success. <h2>, <br> etc are still shown as plain text in the frontend.
I think this has something to do with echo wp_kses_post( $product_attribute[‘value’] ) in product-attributes.php but removing wp_kses_post here and just echo $product_attribute[‘value’] makes no difference at all?
Is there another file that is used before this where kses is in use? Or is there a way to allow certain html markups in kses? I’ve tried hundreds of solutions on the web without look.
Thanks a lot!
The page I need help with: [log in to see the link]
-
Try:
<?php echo html_entity_decode( wp_kses_post( $product_attribute['value'] ) ); ?>
in your custom version of product-attributes.php.
I’m not sure that’s the whole answer but it should get you further.@lorro you’e a genius! I am very close now. It’s working like a charm except for html img src containing urls. I do think this is because of the out of the box behavior of WooCommerce (or is it WordPress?) to make a url clickable everytime it is found. Because of this my images aren’t displayed on the tab. Any idea how to solve this?
The html in the attribute value is altered by filtering before it gets to product-attributes.php, so we need to use the unfiltered value at source. This should apply for this attribute only. So:
add_filter( 'woocommerce_attribute', 'custom_attribute_filter', 10, 2 ); function custom_attribute_filter( $value, $attribute ) { // $value is filtered $attribute_name = $attribute->get_name(); if( 'safety_regulations' == $attribute_name ) { $options = $attribute->get_options(); $value = $options[0]; // unfiltered value $value = html_entity_decode( $value, ENT_COMPAT | ENT_HTML5 ); } return $value; }
The snippet goes in functions.php for your child theme.
I think your site uses HTML5 but this is not the default for html_entity_decode(), so I have specified it in the parameters.
Because html_entity_decode() is applied in the function, there is no need to put it in product-attributes.php and that can be used unchanged.
This code will mean that, if there is anything nasty in the attribute value, which comes from a third party, you will not be protected from it.
Thanks for your time @lorro but the new codes seems like a step backwards. I removed the custom product-attributes.php and applied your code to child themes functions.php but now everything with html isn’t displayed on the frontend anymore at all.
@lorro thanks a lot for your time but the new codes seems like a step backwards. I removed the custom product-attributes.php and applied your code to child themes functions.php but now everything with html isn’t displayed on the frontend anymore at all.
I tried it before posting and it works for me. Debugging via a forum is not so easy.
If you remove the new code, does the attribute show as it did at the beginning?
I assume these are custom attributes (unique per product) and not global attributes (set at Dashboard > Products > Attributes)?
Please try:
add_filter( 'woocommerce_attribute', 'custom_attribute_filter', 10, 2 ); function custom_attribute_filter( $value, $attribute ) { $attribute_name = $attribute->get_name(); print $attribute_name; print '<br><br>'; if( 'safety_regulations' == $attribute_name ) { $options = $attribute->get_options(); print_r( $options ); print '<br><br>'; $value = $options[0]; $value = html_entity_decode( $value, ENT_COMPAT | ENT_HTML5 ); } return $value; }
The print statements will allow you to check the attribute name is what we think it is, and that in the $options array, index 0 is the raw attribute.
Sure @lorro I know that debugging is not so easy. I am so grateful for you answers! I really tried for weeks and hours without considerable success and your answers are giving me the feeling that I am finally getting closer.
“If you remove the new code, does the attribute show as it did at the beginning?”
Yes, when I remove your second code everything’s back to “normal” showing <br> < img src = “…” /> and stuff as plain text.“I assume these are custom attributes (unique per product) and not global attributes (set at Dashboard > Products > Attributes)?”
Yes, that’s true. “safety_regulations” is a custom attribute added on single product level.“This code will mean that, if there is anything nasty in the attribute value, which comes from a third party, you will not be protected from it.”
I know. That’s okay for me. But thank you for mentioning it!So…
I’ve now inserted your third code and we are now a step further again. Html markup is now shown correctly but it’s
a) ouf of it’s place (not below where the fields do belong) on top of the add. information-tab
b) the html is also showing stuff like “array” and “[0]”, [1], etc.
Please see e.g. https://paintappeal.passion4trends.de/produkt/adbl-vampire-liquid-felgenreiniger/?attribute_pa_inhalt=05-lBut it’s the first time that html is shown here completely, so it’s a big, big step!
- This reply was modified 3 years, 10 months ago by dnlcrd.
The out-of-place stuff is just the result of the debugging print statement. It tells us that the html is correct before html_entity_decode().
Please try this one:
add_filter( 'woocommerce_attribute', 'custom_attribute_filter', 10, 2 ); function custom_attribute_filter( $value, $attribute ) { $attribute_name = $attribute->get_name(); if( 'safety_regulations' == $attribute_name ) { $options = $attribute->get_options(); $value = $options[0]; $value = html_entity_decode( $value, ENT_COMPAT | ENT_HTML5 ); print $value; print '<br><br>'; } return $value; }
It does a debug print after the html_entity_decode() line. If the pre-attribute table is correct, then the attribute value includes correctly formatted html after it leave the new function.
So the next thing it could be is that there is another attribute filter which could be modifyng the value. The filter is called ‘woocommerce_display_product_attributes’. Its not used in plain WooCommerce, but its possible that some other plugin or your theme could be using it. To check, you can either do a text search on your site’s code, or temporarily deactivate all plugins except WooCommerce and switch to Storefront, and test.
If you now see correct html in the attribute table, reactivate one-by-one and check to see what plugin or theme is using the filter. Then we will need to decide what to do.
The bad news is that it’s only showing the code without html (neither plaintext nor html). In addition to it it removes the whole content starting after the first | (pipe) written in the text.
The good news is that I deactivated all plugins except WooCommerce and used Storefront theme child with your newest code and it’s the exact same. So it’s at this point not related to my theme or third party plugins.
Try another approach. Remove previous codes. Put this in product-attributes.php. It goes before the
<th class="woocommerce-product-attributes-item__value...
line which is unaltered.<?php if( 'safety_regulations' == $product_attribute['label'] ) { $product_id = $product->get_id(); $ats = get_post_meta( $product_id, '_product_attributes', true ); foreach( $ats as $at ) { if( 'safety_regulations' == $at['name'] ) { $product_attribute['value'] = html_entity_decode( $at['value'], ENT_COMPAT | ENT_HTML5 ); } } } ?>
What this does is fetch the attribute directly from wp_postmeta, and so it avoids any attribute filtering.
@lorro you’re my hero! It worked! Thank you very much for your help!
Hope this post will help other people in the future to solve the same problem!Glad to hear that it worked – thanks for letting us know!
I’ll mark this thread as resolved now. If you have any further questions, I recommend creating a new thread.
@lorro I have a similar problem, I need to be able to use html for product attributes’ values, but I am not displaying them in the aadditional info tab but instead with a custom function underneath the product description – so modifying the attributes php would not work in my case. Do you know how I can allow html in the value fields?
The product description is generated by:
woocommerce/templates/single-product/tabs/description.php
unless the template is overridded by your theme. There are no add_actions() in there, so that’s the template where you’ll need to add your function.Put your edited template in your child theme to prevent it being overridden by updates.
Your function should pull the attributes directly from wp_postmeta as per my previous post, to avoid automated attribute filtering.
@lorro My function is working well, but I cannot save anything with html (or images) as attribute values in backend. My function is this
add_action('woocommerce_single_product_summary', 'display_custom_product_attributues', 36 ); function display_custom_product_attributes() { global $product; $attributes_names = array('attribute1', 'attribute2', 'attribute3'); $attributes_data = array(); foreach ( $attributes_names as $attribute_name ) { if ( $value = $product->get_attribute($attribute_name) ) { $attributes_data[] = $attribute_name . ': ' . $value; } } if ( ! empty($attributes_data) ) { echo '<h3>Info</h3><ul><li>' . implode( '</li><li>', $attributes_data ) . '</ul>'; } }
All my attributes are global. But it is not possible to save any value when you add html or image markup.
- The topic ‘HTML markup in attribute values’ is closed to new replies.