1

In a commerce store that I'm trying out, my product variants have a variant image field.

I need to get an array of all the variant images in my product template.

I know I can do something like

{% set variantImages = product.variants|map(variant => variant.variantImage.one() )}

but I believe this will execute a query for each variant.

I am aware of eager loading in craft, but I am not sure how to use it in this case, as I am not writing a query to get the product or variants - craft auto-injects those into the product template.

How would I eager load the assets of a variant from within the product template?

1 Answer 1

4

You can eager-load elements that were already loaded (like an Entry or Product that Craft set up for you "outside" a template) like this:

{% do craft.app.elements.eagerLoadElements(
  className(product),
  [product],
  [
    ['variants.variantImage', { withTransforms: ['thumbnail'] }],
  ]
) %}

This will load + set any downstream elements, just as though you'd chained an equivalent .with() on the original query.

A couple notes:

  • className() is used to capture the fully-qualified name of the Element class. It's required to let Craft know what kind of eager-loadable properties the specific Element Type has;
  • [product] is an array, because eager-loading is always done in "bulk," even for a single source element;

You can do a similar thing directly on the Variants, if you've got a reference to them, already:

{% set variants = product.variants %}
{% do craft.app.elements.eagerLoadElements(
  className(variants | first),
  variants,
  [
    ['variantImage', { withTransforms: ['thumbnail'] }],
  ]
) %}

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.