1

I've written a short macro to get the first image inside a matrix field.

{% macro firstImage(entry) %}

    {% set image = 'hello' %}

    {% if entry.sliderMatrix.total() %}
        {% set block = entry.sliderMatrix|first %}
        {% set image = block.image|first %}
    {% endif %}

    {{ image.url }}

{% endmacro %}

The code throws this error: Impossible to access an attribute ("url") on a string variable ("hello")

{{ image.url }} inside the if statement works fine.

{{ image }} outside the if statement works too.

Is there anything I don't know or it's even a bug?

  • The code seems to be alright. Can you detail how your matrix is set up? Maybe a screenshot? – Aaron Berkowitz Mar 17 '15 at 21:10
2

Your syntax is close, but not quite right and you're setting a variable as a string and later setting it as an Element Model. I think you're searching for something closer to this:

{% macro firstImage(entry) %}

    {% if entry.sliderMatrix.total() %}
        {% set block = entry.sliderMatrix.first %}
        {% set image = block.image.first %}
    {% endif %}

    {% if image is defined and image %}
        {{ image.url }}
    {% endif %}

{% endmacro %}
|improve this answer|||||
  • This syntax is much better! May I suggest if image is defined? – Lindsey D Mar 17 '15 at 21:14
  • You surely may :-) – Peter Tell Mar 17 '15 at 21:14
  • 1
    @Christian if that asset field is not marked as required you should also check if first() actually returns an image, so use this conditional {% if image is defined and image %}. – carlcs Mar 17 '15 at 22:43
  • 1
    Even if that asset field is marked as required you should still check if first() actually returns an image. If that required image is deleted after the entry is created you will end up with an entry with no image. – Marion Newlevant Mar 18 '15 at 8:10
3

Hard to say for sure, but here's what I suspect... You may have multiple instances of firstImage being called from your main template.

For some of those instances, entry.sliderMatrix.total is greater than zero. For other instances, entry.sliderMatrix.total is equal to zero. And of course, when entry.sliderMatrix.total is equal to zero, your if statement will be bypassed.

Realistically, you shouldn't have the image.url call outside of your if statement. Because any time the if statement evaluates to false, then the image variable won't be what you want it to be. In fact, you'll get that exact error, since image will still be set to a string.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.