<blockquote>
  <p>I'm basing this response on the incomplete statement <code>{% set image = craft.assets.filename('').one() %}</code>.</p>
</blockquote>

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

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

<p>This does a couple things:</p>

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

<p>Always check you have results before attempting to access properties of your image:</p>

<pre><code>{% if exampleImage %}
    &lt;img src="{{ exampleImage.url }}"&gt;
{% endif %}
</code></pre>

<p>I think the original problem you were encountering was that (by default) the <code>filename</code> query parameter matches strictly, meaning that <em>your SKU would need to be the complete filename</em> in order to be returned. You can view the fuzzy-matching syntax/options in the <a href="https://docs.craftcms.com/v3/dev/element-queries/asset-queries.html#parameters" rel="nofollow noreferrer">Asset Query documentation</a>.</p>

<hr>

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

<pre><code>{# 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: #}

&lt;img src="{{ image.url }}"&gt;
</code></pre>

CC BY-SA 4.0
2019-06-17T20:14:00.763Z
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!!
Jeremy Latham
CC BY-SA 4.0
2019-06-17T20:16:41.217Z
Glad it helped—good catch! ✌️
August Miller
CC BY-SA 4.0
2019-06-17T19:50:52.197Z
2019-06-17T20:15:47.560Z
2019-06-17T20:15:47.560Z
August Miller
<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>How can I get the results of productPic in to the assets query below it?</p>

<pre><code>{% for rental in rentals %}
&lt;li class="cell text-center"&gt;
    &lt;a href="{{ rental.url }}"&gt;

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

        {# 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() %}
        &lt;img src="{{ image.getUrl() }}" alt="No Image Available" /&gt;

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

        {% endif %}
    &lt;/a&gt;
    &lt;br /&gt;
    &lt;a href="{{ rental.url }}"&gt;{{ rental.title }}&lt;/a&gt;
&lt;/li&gt;
{% endfor %}
</code></pre>

CC BY-SA 4.0
2019-06-21T00:16:21.427Z
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.
Jeremy Daalder
<craft3><assets><plugin-craftcommerce>
Asset Filename Query using Product SKU
# Asset Filename Query using Product SKU

(Asked by: username_0 on 2019-06-17)

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 %}

    

        {# If there's a product image, crop and display the product image.#}
        {% if rental.productImage|length %}
        {% set image = rental.productImage.one() %}
        

        {# 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() %}
        

        {# Else, display a stock image that says no image available. #}
        {% else %}
        {% set image = craft.assets.id(9225).one() %}
        

        {% endif %}
    
    
    {{ rental.title }}

{% endfor %}

**Tags:** craft3, assets, plugin-craftcommerce

> **Comments:**
> **username_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.  

---

## 1 answers

### Answer by username_2 on 2019-06-17. Score: 1 | Accepted answer

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:

Collapses the transformation of a product into a search string using Twig's string interpolation, and the filter you'd applied;
Appends .* to match all extensions (optional, but recommended, in the event you have some PNG, JPG, and JPEG images in your library);
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 %}
    
{% 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: #}

> **Comments:**
> **username_0**: 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!!  
> **username_2**: Glad it helped—good catch! ✌️  

---

