1

I'm moving an e-commerce site over from EE. Many of the products have a "product image". Many do not, but we have an assets directory full of images that match their SKUs.

When listing the products by category, I want to call images in the following order: 1. If there's a product image, crop and display the product image. 2. Else if there's an asset filename that matches the product SKU, crop and display that asset. 3. Else, display a stock image that says no image available.

I'm running in to a problem with step 2. I can display the product SKU in lowercase in the template, but I don't know how to make the asset query using the product SKU.

How can I get the results of productPic in to the assets query below it?

{% for rental in rentals %}
<li class="cell text-center">
    <a href="{{ rental.url }}">

        {# If there's a product image, crop and display the product image.#}
        {% if rental.productImage|length %}
        {% set image = rental.productImage.one() %}
        <img src="{{ image.getUrl(thumb) }}" alt="{{ rental.title }}" />

        {# Elseif there's an asset filename that matches the product SKU, crop and display that asset. Using rental.title temporarily to trigger this conditional. #}
        {% elseif rental.title|length %}
        {% set variant = rental.defaultVariant %}
        {% set productPic = variant.sku|lower %}
        {{ productPic }}
        {% set image = craft.assets.filename('').one() %}
        <img src="{{ image.getUrl() }}" alt="No Image Available" />

        {# Else, display a stock image that says no image available. #}
        {% else %}
        {% set image = craft.assets.id(9225).one() %}
        <img src="{{ image.getUrl() }}" alt="No Image Available" />

        {% endif %}
    </a>
    <br />
    <a href="{{ rental.url }}">{{ rental.title }}</a>
</li>
{% endfor %}
1
  • Is there a reason you don't want to go the traditional approach and attach an asset field to your product entries and associate the images that way? Basing things on filename searches seems a brittle strategy long term, and not great from an AX point of view. Commented Jun 21, 2019 at 0:16

1 Answer 1

1

I'm basing this response on the incomplete statement {% set image = craft.assets.filename('').one() %}.

To get an asset named the same as the SKU of a Product's default Variant, try this:

{% set exampleImage = craft.assets({
    filename: "#{myProduct.defaultVariant.sku | lower}.*"
}).one() %}

This does a couple things:

  1. Collapses the transformation of a product into a search string using Twig's string interpolation, and the filter you'd applied;
  2. Appends .* to match all extensions (optional, but recommended, in the event you have some PNG, JPG, and JPEG images in your library);
  3. Executes the query and returns a single Asset Element or null.

Always check you have results before attempting to access properties of your image:

{% if exampleImage %}
    <img src="{{ exampleImage.url }}">
{% endif %}

I think the original problem you were encountering was that (by default) the filename query parameter matches strictly, meaning that your SKU would need to be the complete filename in order to be returned. You can view the fuzzy-matching syntax/options in the Asset Query documentation.


With respect to the overall structure of the code, I'd recommend an approach like this:

{# First, look for an attached image: #}

{% set image = myProduct.productImage.one() %}

{# If there wasn't one, try looking in the Asset library: #}

{% if not image %}
    {% set image = craft.assets({
        filename: "#{myProduct.defaultVariant.sku | lower}.*"
    }).one() %}
{% endif %}

{# We might still be missing an image. If so, fall back to fetching a specific one: #}

{% if not image %}
    {% set image = craft.assets({
        id: 9225
    }).one() %}
{% endif %}

{# Ok, now we're guaranteed to have one of the above images—we can safely use `image` the same, regardless of where it came from: #}

<img src="{{ image.url }}">
2
  • This is it! Thank you so much. You missed a closing tag on the filename query but otherwise, you nailed it. Might as well fix the closing tag in case anyone stumbles upon this. I'll check it off after that. Thank again!! Commented Jun 17, 2019 at 20:14
  • Glad it helped—good catch! ✌️ Commented Jun 17, 2019 at 20:16

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.