I have a commerce project with a specific product type using an attribute to generate variation.

Variation product has two specific fields that I want to hide switch attribute.

I implemented hook_preprocess_commerce_product to check this. In my hook, I check for a variation in POST (purchased_entity) or GET (v=xyz). If no one is found, I retrieve the default variation and set into the $variables array a new value called "is_custom_variation". This value is set to TRUE when the variation is a "custom" one. Only one variation in a product can be a custom variation, other are standard variations.

The "add to cart" form use a "select" form element to (ajax) switch between variations.

In the product template (commerce-product--full.html.twig) I added the following code :

<article{{ attributes }}>
{% if is_custom_variation %}
  {{- product|without('variation_attributes', 'variation_field_1', 'variation_field_2') -}}
{% else %}
  {{- product|without('variation_attributes') -}}
{% endif %}

Strange thing appears when I test the code :

  • I load the product page with the default variation as "custom" variation : field 1 and field 2 are hidden. When I switch to another "non-custom" variation, fields are hidden too.

  • I load the product page with a "non-custom" variation : field 1 and field 2 are displayed. When I switch to the "custom" variation, fields are displayed too.

By enabling xdebug, I see that each time the template is called, the variable "is_custom_variation" is correctly set (TRUE on custom variation, FALSE otherwise)

Maybe anyone can point me what is wrong on my implementation... I don't know why the template is using always the same process after the first display. Is it related to ajax reload of the variation ?

Thanks in advance for any suggestion.

1 Answer 1


If you have other input data(url, query params, timestamp, cookie, etc) than $variables in your HOOK_preprocess you have to update your cache rules otherwise first time you get trough that hook will get cached for the rest of iterations of same $variables input.

In your case I suggest using cache context or cache tags where they change based on POST and GET variables.


  • Maybe I don't understand the way it work, but render cache is not enabled, and the ajax call get a render array and process it. I tried a lot of combination to add cache contexts or tags to my render array in the preprocess function but result is always the same. I thank that using condition in twig template was the correct way to have a conditional display but maybe I'm wrong. Always is that I don't know how to change #cache key of my render array to achieve my goal. Other solution I see is to user JS with eventSubscriber on ProductEvents::PRODUCT_VARIATION_AJAX_CHANGE but seems hacky...
    – titouille
    Nov 16, 2020 at 21:01

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.