Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Conversation

@alexflorisca
Copy link
Contributor

This fixes a bug where we were deriving a class name from a translatable string, which could be different depending on the language of the user and therefore pretty useless for styling for an international store.

Fixes #6512

Testing

User Facing Testing

  1. Add an item to your cart that has multiple variants. E.g. Hoodie (Blue, Logo)
  2. Go to the Cart Block
  3. Inspect the text for one of the variants (e.g. Colour: Blue)
  4. Make sure there is a class called wc-block-components-product-details__item on the <li> element. This should be a child of <ul className="wc-block-components-product-details">
  5. Change the language of your store
  6. Refresh the cart page
  7. Repeat steps 3 and 4. You should see the same result.
  • Do not include in the Testing Notes

WooCommerce Visibility

  • WooCommerce Core
  • Feature plugin
  • Experimental

Performance Impact

Changelog

Fixed a bug with a class name deriving from a translatable string

@alexflorisca alexflorisca added type: bug The issue/PR concerns a confirmed bug. focus: blocks Specific work involving or impacting how blocks behave. block: cart Issues related to the cart block. block: checkout Issues related to the checkout block. labels Aug 17, 2022
@rubikuserbot rubikuserbot requested review from a team and opr and removed request for a team August 17, 2022 15:52
@github-actions
Copy link
Contributor

The release ZIP for this PR is accessible via:

https://wcblocks.wpcomstaging.com/wp-content/uploads/woocommerce-gutenberg-products-block-6914.zip

@github-actions
Copy link
Contributor

github-actions bot commented Aug 17, 2022

Size Change: -107 B (0%)

Total Size: 871 kB

Filename Size Change
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.25 kB -20 B (0%)
build/cart-frontend.js 47.1 kB +1 B (0%)
build/cart.js 41.8 kB -17 B (0%)
build/checkout-blocks/order-summary-cart-items-frontend.js 3.64 kB -18 B (0%)
build/checkout.js 43.2 kB -23 B (0%)
build/mini-cart-contents.js 22.9 kB -30 B (0%)
ℹ️ View Unchanged
Filename Size
build/active-filters-frontend.js 7.34 kB
build/active-filters.js 8.01 kB
build/all-products-frontend.js 18.1 kB
build/all-products.js 33.7 kB
build/all-reviews.js 7.79 kB
build/attribute-filter-frontend.js 22.1 kB
build/attribute-filter.js 13.1 kB
build/blocks-checkout.js 17.4 kB
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.16 kB
build/cart-blocks/cart-express-payment-frontend.js 5.09 kB
build/cart-blocks/cart-items-frontend.js 299 B
build/cart-blocks/cart-line-items-frontend.js 429 B
build/cart-blocks/cart-order-summary-frontend.js 1.1 kB
build/cart-blocks/cart-totals-frontend.js 321 B
build/cart-blocks/empty-cart-frontend.js 346 B
build/cart-blocks/filled-cart-frontend.js 781 B
build/cart-blocks/order-summary-coupon-form-frontend.js 2.65 kB
build/cart-blocks/order-summary-discount-frontend.js 2.15 kB
build/cart-blocks/order-summary-fee-frontend.js 274 B
build/cart-blocks/order-summary-heading-frontend.js 454 B
build/cart-blocks/order-summary-shipping--checkout-blocks/order-summary-shipping-frontend.js 6.37 kB
build/cart-blocks/order-summary-shipping-frontend.js 426 B
build/cart-blocks/order-summary-subtotal-frontend.js 274 B
build/cart-blocks/order-summary-taxes-frontend.js 434 B
build/cart-blocks/proceed-to-checkout-frontend.js 1.15 kB
build/checkout-blocks/actions-frontend.js 1.42 kB
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.12 kB
build/checkout-blocks/billing-address-frontend.js 891 B
build/checkout-blocks/contact-information-frontend.js 2.83 kB
build/checkout-blocks/express-payment-frontend.js 5.38 kB
build/checkout-blocks/fields-frontend.js 345 B
build/checkout-blocks/order-note-frontend.js 1.07 kB
build/checkout-blocks/order-summary-coupon-form-frontend.js 2.8 kB
build/checkout-blocks/order-summary-discount-frontend.js 2.26 kB
build/checkout-blocks/order-summary-fee-frontend.js 276 B
build/checkout-blocks/order-summary-frontend.js 1.11 kB
build/checkout-blocks/order-summary-shipping-frontend.js 604 B
build/checkout-blocks/order-summary-subtotal-frontend.js 274 B
build/checkout-blocks/order-summary-taxes-frontend.js 434 B
build/checkout-blocks/payment-frontend.js 7.7 kB
build/checkout-blocks/shipping-address-frontend.js 1.03 kB
build/checkout-blocks/shipping-methods-frontend.js 4.75 kB
build/checkout-blocks/terms-frontend.js 1.23 kB
build/checkout-blocks/totals-frontend.js 325 B
build/checkout-frontend.js 49.3 kB
build/featured-category.js 13.2 kB
build/featured-product.js 13.5 kB
build/general-style-rtl.css 1.29 kB
build/general-style.css 1.29 kB
build/handpicked-products.js 7.37 kB
build/legacy-template.js 2.79 kB
build/mini-cart-component-frontend.js 16.8 kB
build/mini-cart-contents-block/empty-cart-frontend.js 365 B
build/mini-cart-contents-block/filled-cart-frontend.js 229 B
build/mini-cart-contents-block/footer--mini-cart-contents-block/products-table-frontend.js 4.69 kB
build/mini-cart-contents-block/footer-frontend.js 6.98 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/products-table-frontend.js 289 B
build/mini-cart-contents-block/shopping-button-frontend.js 288 B
build/mini-cart-contents-block/title-frontend.js 367 B
build/mini-cart-frontend.js 1.71 kB
build/mini-cart.js 4.58 kB
build/price-filter-frontend.js 13.3 kB
build/price-filter.js 9.17 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-category-list--product-image--product-price--product-r--a0326d00.js 223 B
build/product-add-to-cart--product-button--product-image--product-title.js 2.65 kB
build/product-add-to-cart-frontend.js 6.95 kB
build/product-add-to-cart.js 6.88 kB
build/product-best-sellers.js 7.71 kB
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 436 B
build/product-button--product-image--product-rating--product-sale-badge--product-title.js 300 B
build/product-button-frontend.js 1.88 kB
build/product-button.js 1.57 kB
build/product-categories.js 2.41 kB
build/product-category-list-frontend.js 879 B
build/product-category-list.js 504 B
build/product-category.js 8.69 kB
build/product-image-frontend.js 1.89 kB
build/product-image.js 1.59 kB
build/product-new.js 7.72 kB
build/product-on-sale.js 8.03 kB
build/product-price-frontend.js 1.9 kB
build/product-price.js 1.51 kB
build/product-query.js 648 B
build/product-rating-frontend.js 1.16 kB
build/product-rating.js 742 B
build/product-sale-badge-frontend.js 1.13 kB
build/product-sale-badge.js 802 B
build/product-search.js 2.65 kB
build/product-sku-frontend.js 381 B
build/product-sku.js 379 B
build/product-stock-indicator-frontend.js 993 B
build/product-stock-indicator.js 624 B
build/product-summary-frontend.js 1.29 kB
build/product-summary.js 918 B
build/product-tag-list-frontend.js 872 B
build/product-tag-list.js 498 B
build/product-tag.js 8.09 kB
build/product-title-frontend.js 1.31 kB
build/product-title.js 923 B
build/product-top-rated.js 7.95 kB
build/products-by-attribute.js 8.63 kB
build/reviews-by-category.js 11.2 kB
build/reviews-by-product.js 12.3 kB
build/reviews-frontend.js 7.01 kB
build/single-product-frontend.js 21.4 kB
build/single-product.js 10.1 kB
build/stock-filter-frontend.js 7.5 kB
build/stock-filter.js 7.45 kB
build/vendors--cart-blocks/cart-line-items--cart-blocks/cart-order-summary--cart-blocks/order-summary-shi--c02aad66-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.14 kB
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--5b8feb0b-frontend.js 4.85 kB
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--decc3dc6-frontend.js 19.1 kB
build/vendors--mini-cart-contents-block/footer-frontend.js 6.86 kB
build/vendors--product-add-to-cart-frontend.js 7.53 kB
build/wc-blocks-data.js 9.87 kB
build/wc-blocks-editor-style-rtl.css 5.1 kB
build/wc-blocks-editor-style.css 5.1 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 930 B
build/wc-blocks-registry.js 2.7 kB
build/wc-blocks-shared-context.js 1.52 kB
build/wc-blocks-shared-hocs.js 1.14 kB
build/wc-blocks-style-rtl.css 22.9 kB
build/wc-blocks-style.css 22.8 kB
build/wc-blocks-vendors-style-rtl.css 1.95 kB
build/wc-blocks-vendors-style.css 1.95 kB
build/wc-blocks-vendors.js 54.5 kB
build/wc-blocks.js 2.63 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB

compressed-size-action

Copy link
Contributor

@nielslange nielslange left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! ⛴

@github-actions github-actions bot added this to the 8.4.0 milestone Aug 22, 2022
@tarhi-saad tarhi-saad self-requested a review August 29, 2022 07:19
Copy link
Contributor

@tarhi-saad tarhi-saad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @alexflorisca! We have two failing unit tests. I believe you need to update the test snapshots for it to pass. And make sure to update your branch with trunk!

@tarhi-saad tarhi-saad self-requested a review August 29, 2022 10:44
@tarhi-saad tarhi-saad merged commit c410644 into trunk Aug 29, 2022
@tarhi-saad tarhi-saad deleted the fix/6512-translatable-string-as-classname branch August 29, 2022 10:46
@helgatheviking
Copy link
Contributor

@tarhi-saad This is causing problems for me with Mix and Match as now there's no way to distinguish between the meta items at all. There still needs to be a unique identifying class, and ideally have it stay consistent regardless of the site language. See also my comment here

@tarhi-saad
Copy link
Contributor

Hello, @helgatheviking! Thank you for reporting this issue!

@alexflorisca's, if you can confirm that the class names aren't translatable, let's revert the changes of this PR! Otherwise, we can open a new issue to add support for unique identifying class.

@alexflorisca
Copy link
Contributor Author

@helgatheviking I tested this with the product addons plugin and these didn't translate for me. Can you tell us what plugin you're using and how you're seeing the classname strings translated so we can try to replicate?

@helgatheviking
Copy link
Contributor

helgatheviking commented Sep 20, 2022

Hi @alexflorisca thanks for the update. I am working with my plugin WooCommerce Mix and Match Products... so add a Mix and Match product to the cart and then look at the checkout block. I believe the issue also existed with Bundled Products too. What is the specific commit I should test against?

@alexflorisca
Copy link
Contributor Author

You can test against this commit: 6c68e0c

@helgatheviking
Copy link
Contributor

Hi @alexflorisca I think that is the commit where this change was introduced no? The unique class names aren't present in that commit, so I think I need to go back to the one before it...

@alexflorisca
Copy link
Contributor Author

alexflorisca pushed a commit that referenced this pull request Sep 21, 2022
@helgatheviking
Copy link
Contributor

helgatheviking commented Sep 21, 2022

Thanks, Alex. Maybe it's caching but I can't get the class name to render for anything. 😓 in typical fashion, I can't get the build tools to build.

alexflorisca pushed a commit that referenced this pull request Sep 21, 2022
@alexflorisca
Copy link
Contributor Author

alexflorisca commented Sep 21, 2022

@helgatheviking We've just reverted this in #7191 so if you get the latest trunk, you should have the classname back. Apologies, I think I deleted that class too soon.

@helgatheviking
Copy link
Contributor

helgatheviking commented Sep 21, 2022

Thanks @alexflorisca I still see the class name is translatable because the key that is displayed must be translatable to support multilingual sites. Here's a test case:

/**
 * Add cart item data to items.
 *
 * @param  array  $data
 * @param  array  $cart_item
 * @return array
 */
function kia_test_cart_item_data( $data, $cart_item ) {

    $data[] = array(
                'key'   => esc_html__( 'Color', 'your-textdomain' ),
                'value' => esc_html__( 'Blue', 'your-textdomain' ),
	);
    return $data;
}
add_filter( 'woocommerce_get_item_data', 'kia_test_cart_item_data', 10, 2 );

/**
 * Change text strings
 *
 * @link http://codex.wordpress.org/Plugin_API/Filter_Reference/gettext
 */
function kia_test_translate_text_strings( $translated_text, $text, $domain ) {
	
	if ( 'your-textdomain' === $domain && 'fr_FR' === get_locale() ) {
		switch ( $translated_text ) {
			case 'Color' :
				$translated_text = __( 'Couleur', 'your-textdomain' );
				break;
			case 'Blue' :
				$translated_text = __( 'Bleu', 'your-textdomain' );
				break;
		}
	}
	return $translated_text;
}
add_filter( 'gettext', 'kia_test_translate_text_strings', 20, 3 );

When I switch my site to the French language, the class changes from wc-block-components-product-details__color to wc-block-components-product-details__couleur. This makes it very tricky to style with CSS.

image

If I change my above snippet to design key and name:

/**
 * Add cart item data to items.
 *
 * @param  array  $data
 * @param  array  $cart_item
 * @return array
 */
function kia_test_cart_item_data( $data, $cart_item ) {

    $data[] = array(
		'key' => 'color',
                'name'   => esc_html__( 'Color', 'your-textdomain' ),
                'value' => esc_html__( 'Blue', 'your-textdomain' ),
	);
    return $data;
}
add_filter( 'woocommerce_get_item_data', 'kia_test_cart_item_data', 10, 2 );

Then class name is not translated, but neither is the user-facing text:

image

I am still looking for a way to display the translated text to users but have a static class name. These two things shouldn't be linked in my opinion.

@alexflorisca
Copy link
Contributor Author

alexflorisca commented Sep 21, 2022

Yeah I get you. So the problem we have is that with the scenario you described above, any item inside the $data[] array can be translated right? That's the only dynamic data that we have to generate unique classnames from, so in theory we can't use any information inside $data[]. We could loop through a for loop and add a number on the end of the classname for each item - but I don't think that's very useful as it's not a sure way of targeting a specific item, only its place in the list. So I'm not really sure how to solve this one. I've reached out to my team to see if anyone else has any ideas

@helgatheviking
Copy link
Contributor

I agree a number would be pretty useless. I would never be able to predict what position the item was in the cart. Can key and name be decoupled so that the class is generated from key and name is the visible label? Can a class param be introduced? Is there a restriction on what data can be in the $data[] array?

@alexflorisca
Copy link
Contributor Author

Unfortunately we can't decouple key from name as we need to support both to keep compatible with WC Core (more details in this issue). $data[] should ideally be the same as WC core and provide key and display params but it will also work with name and value.

We could potentially introduce a class param here and pass that as a the classname. I'd love to hear if this would work for @jimjasson as well as the product addons plugin does something similar here?

@jimjasson
Copy link

Hey @alexflorisca,

Thank you for investigating this further!

The solution you propose is not 100% clear to me. Would you mind sharing an example of how the code would look like with this change? Moreover, can you please share a screenshot of the DOM structure in the frontend when your changes are active? Which classes will be available at the point where the deprecated class used to exist?

@alexflorisca
Copy link
Contributor Author

alexflorisca commented Sep 27, 2022

My bad @jimjasson, that wasn't a great explanation. What I mean is that at the moment, we can add extra fields to a product by using the woocommerce_get_item_data filter as mentioned above by @helgatheviking . At the moment, it looks like we only use the key and display props of the item variant. We could include an extra property here classname (or similar) to let users specify a class name to apply to that variant.

The screenshot below shows the class names of the two variant labels, colour and logo. Notice the two <li> elements, with class="wc-block-components-product-details__color" and class="wc-block-components-product-details__logo".

Screenshot 2022-09-27 at 10 48 05

At the moment these are generated on the client from the key or name property of the item data, like so:

const name = item?.key || item.name || '';
const className = name ? `wc-block-components-product-details__${ kebabCase(name) }` : '';

The item here comes from the woocommerce_get_item_data filter, where it's equivalent to $data

function kia_test_cart_item_data( $data, $cart_item ) {

    $data[] = array(
                'key'   => esc_html__( 'Color', 'your-textdomain' ),
                'value' => esc_html__( 'Blue', 'your-textdomain' ),
	);
    return $data;
}
add_filter( 'woocommerce_get_item_data', 'kia_test_cart_item_data', 10, 2 );

What @helgatheviking is proposing is adding an extra class property within the filter where we add the variation data for a product, so that this can be available on the client and used instead of deriving the class from the key or name properties (which may be translated).

function kia_test_cart_item_data( $data, $cart_item ) {

    $data[] = array(
                'key'   => esc_html__( 'Color', 'your-textdomain' ),
                'value' => esc_html__( 'Blue', 'your-textdomain' ),
                'class' => esc_html__( 'wc-block-components-product-details__color', 'your-textdomain' ),

	);
    return $data;
}
add_filter( 'woocommerce_get_item_data', 'kia_test_cart_item_data', 10, 2 );

So in this example, the final DOM will look the same, but the class name is explicitly given rather than derived from the name or key props.

Does that make sense?

@helgatheviking
Copy link
Contributor

I like it! A class name we can specify would give parity to the php cart/order row class filter too.

@jimjasson
Copy link

Gotcha @alexflorisca -- thank you for the detailed explanation! Yes, that would be helpful for us too!

@alexflorisca
Copy link
Contributor Author

alexflorisca commented Sep 27, 2022

Great, I've created an issue to do this. Bare in mind that once this solution is merged and released, your tests will probably start failing again @jimjasson, until you make the required change on your side.

@jimjasson
Copy link

Thank you @alexflorisca !

your tests will probably start failing again @jimjasson, until you make the required change on your side.

Yes, this makes sense.

I will keep a close eye on the progress of this issue -- I would really appreciate it though, if you could ping me when this is implemented + close to release. Thanks! 🚀

@alexflorisca
Copy link
Contributor Author

@jimjasson pinging you as this is now complete and merged to trunk in #7328

@PanosSynetos
Copy link
Contributor

Thanks @alexflorisca for the ping. I just tested and I see the classes are back

@helgatheviking
Copy link
Contributor

@PanosSynetos you should now be able to add a class that doesn't change via translation.

@PanosSynetos
Copy link
Contributor

Awesome :) Thanks for the ping Kathy!

senadir pushed a commit to senadir/woocommerce-blocks that referenced this pull request Nov 12, 2022
* Add a static class name for the product details item instead of the translatable string

* Update Jest snapshot

Co-authored-by: Saad Tarhi <[email protected]>
senadir pushed a commit to senadir/woocommerce-blocks that referenced this pull request Nov 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

block: cart Issues related to the cart block. block: checkout Issues related to the checkout block. focus: blocks Specific work involving or impacting how blocks behave. type: bug The issue/PR concerns a confirmed bug.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ProductDetails should have a translation independent class name on the <li> element

7 participants