<p>Another way to do this would be to assemble a list of the entry IDs that you want to look for a hero image in, in order, and then finding the first hero image related to one of those entries.</p>

<p>To create that list of entry IDs, we start by creating an array of the current entry’s ID, and <a href="http://twig.sensiolabs.org/doc/filters/merge.html" rel="nofollow noreferrer"><code>merge</code></a> it with an array of the entry’s <a href="http://buildwithcraft.com/docs/templating/entrymodel#getAncestors" rel="nofollow noreferrer">ancestors’</a> IDs in <a href="http://twig.sensiolabs.org/doc/filters/reverse.html" rel="nofollow noreferrer"><code>reverse</code></a> order:</p>



<pre class="lang-twig prettyprint-override"><code>{% set ancestorIds = entry.getAncestors().ids() %}
{% set entryIds = [ entry.id ]|merge( ancestorIds|reverse ) %}
</code></pre>

<p>Now that we have our list of entry IDs that could have the hero image, next up we need to find the first one that actually has one. We can do that with <a href="http://buildwithcraft.com/docs/templating/craft.entries" rel="nofollow noreferrer"><code>craft.entries</code></a> and passing <code>:notempty:</code> to the relational field param:</p>

<pre class="lang-twig prettyprint-override"><code>{% set heroEntry = craft.entries({
    id: entryIds,
    fixedOrder: true,
    hero: ':notempty:',
}).first() %}
</code></pre>

<p>There’s a chance that no entry was found, so before you start interacting with <code>heroEntry</code> you should make sure that <a href="http://buildwithcraft.com/docs/templating/elementcriteriamodel#first" rel="nofollow noreferrer"><code>first()</code></a> actually returned something.</p>

<pre class="lang-twig prettyprint-override"><code>{% if heroEntry %}
    &lt;img src="{{ heroEntry.hero.first().url }}"&gt;
{% endif %}
</code></pre>

CC BY-SA 3.0
2014-10-24T15:59:10.873Z
Nice one Brandon, I like it more than my solution (even though I was a little proud of that recursive macro)! :)
carlcs
CC BY-SA 3.0
2014-10-24T16:02:13.737Z
@carlcs Hah, your solution is great too! Just thought it was worth mentioning the alternative. Performance-wise it's probably a toss-up if the hero image is never more than 3 levels away, though this one will be a little more scalable if it could be a few levels deeper.
Brandon Kelly
CC BY-SA 3.0
2014-10-24T12:21:49.053Z
2017-10-25T12:24:21.003Z
2017-10-25T12:24:21.003Z
Brandon Kelly
<p>You can get your entry's parent entry with <a href="http://buildwithcraft.com/docs/templating/entrymodel#getParent" rel="nofollow noreferrer"><code>getParent()</code></a>. Use this entry method in a conditional, if your entry has no hero image set.</p>

<p>You can nest the code to climb up all of your structure's levels:</p>

<pre><code>{# Check if entry has hero image #}
{% if entry.hero.first() %}
    {{ entry.hero.first().url }}
{% else %}

    {# Check the parent entry #}
    {% if entry.getParent().hero.first() %}
        {{ entry.getParent().hero.first().url }}
    {% else %}

        {# Check the entry 2 levels above #}
        {% if entry.getParent().getParent().hero.first() %}
            {{ entry.getParent().getParent().hero.first().url }}
        {% else %}

            {# ... Oh no, we're not finished yet :( #}

        {% endif %}

    {% endif %}

{% endif %}
</code></pre>

<p>Yes, that's not good code. That's why I recommend to use the same technique in <a href="http://twig.sensiolabs.org/doc/tags/macro.html" rel="nofollow noreferrer">a macro</a>, that you can call recursively:</p>

<pre><code>{% macro showHero(thisRecursionEntryModel) %}

    {% import _self as self %}

    {# Check if entry has hero image #}
    {% if thisRecursionEntryModel.hero.first() %}
        {{ thisRecursionEntryModel.hero.first().url }}
    {% else %}

        {# Check the entry's ancestors recursively #}
        {% if thisRecursionEntryModel.getParent() %}
            {{ self.showHero(thisRecursionEntryModel.getParent()) }}
        {% endif %}

    {% endif %}

{% endmacro %}

{% import _self as self %}
{{ self.showHero(entry) }}
</code></pre>

<p>You can also import the macro from a file, if you want to use it in more than one template file or just like your code to be modular:</p>

<pre><code>{% import '_includes/macros.html' as macros %}
{{ macros.showHero(entry) }}
</code></pre>

CC BY-SA 3.0
2014-10-24T12:11:30.827Z
Thanks for the edit, @Brandon. I wrote this not with assets in mind and simply added `.url` at the end.
carlcs
CC BY-SA 3.0
2014-10-24T14:33:01.583Z
Perfect, thank you. I tried something along these lines but had syntax issues. @Brandon, thanks for clarifying my title as well.
Lance
CC BY-SA 3.0
2014-10-24T09:59:28.883Z
2017-10-25T12:30:40.760Z
2017-10-25T12:30:40.760Z
carlcs
<p>I have a structure that goes up to 4 levels deep. Each page has a field for a 'hero' image. If a child page does not have this field filled out I would like to traverse up the structure and find the closest parent entry with this field set. Basically some 'sections' would have a default hero image added to the top level parent while others may have a specific image for each child page.</p>

<entries><structure><field><elementcriteriamodel><children>
How do I find the closest parent entry with an Assets field filled in?
# How do I find the closest parent entry with an Assets field filled in?

(Asked by: username_0 on 2014-10-24)

I have a structure that goes up to 4 levels deep. Each page has a field for a 'hero' image. If a child page does not have this field filled out I would like to traverse up the structure and find the closest parent entry with this field set. Basically some 'sections' would have a default hero image added to the top level parent while others may have a specific image for each child page.

**Tags:** entries, structure, field, elementcriteriamodel, children


---

## 2 answers

### Answer by username_2 on 2014-10-24. Score: 6 | Accepted answer

You can get your entry's parent entry with getParent(). Use this entry method in a conditional, if your entry has no hero image set.
You can nest the code to climb up all of your structure's levels:
{# Check if entry has hero image #}
{% if entry.hero.first() %}
    {{ entry.hero.first().url }}
{% else %}

    {# Check the parent entry #}
    {% if entry.getParent().hero.first() %}
        {{ entry.getParent().hero.first().url }}
    {% else %}

        {# Check the entry 2 levels above #}
        {% if entry.getParent().getParent().hero.first() %}
            {{ entry.getParent().getParent().hero.first().url }}
        {% else %}

            {# ... Oh no, we're not finished yet :( #}

        {% endif %}

    {% endif %}

{% endif %}

Yes, that's not good code. That's why I recommend to use the same technique in a macro, that you can call recursively:
{% macro showHero(thisRecursionEntryModel) %}

    {% import _self as self %}

    {# Check if entry has hero image #}
    {% if thisRecursionEntryModel.hero.first() %}
        {{ thisRecursionEntryModel.hero.first().url }}
    {% else %}

        {# Check the entry's ancestors recursively #}
        {% if thisRecursionEntryModel.getParent() %}
            {{ self.showHero(thisRecursionEntryModel.getParent()) }}
        {% endif %}

    {% endif %}

{% endmacro %}

{% import _self as self %}
{{ self.showHero(entry) }}

You can also import the macro from a file, if you want to use it in more than one template file or just like your code to be modular:
{% import '_includes/macros.html' as macros %}
{{ macros.showHero(entry) }}

> **Comments:**
> **username_2**: Thanks for the edit, @Brandon. I wrote this not with assets in mind and simply added `.url` at the end.  
> **username_0**: Perfect, thank you. I tried something along these lines but had syntax issues. @Brandon, thanks for clarifying my title as well.  

---

### Answer by username_1 on 2014-10-24. Score: 7

Another way to do this would be to assemble a list of the entry IDs that you want to look for a hero image in, in order, and then finding the first hero image related to one of those entries.
To create that list of entry IDs, we start by creating an array of the current entry’s ID, and merge it with an array of the entry’s ancestors’ IDs in reverse order:
{% set ancestorIds = entry.getAncestors().ids() %}
{% set entryIds = [ entry.id ]|merge( ancestorIds|reverse ) %}

Now that we have our list of entry IDs that could have the hero image, next up we need to find the first one that actually has one. We can do that with craft.entries and passing :notempty: to the relational field param:
{% set heroEntry = craft.entries({
    id: entryIds,
    fixedOrder: true,
    hero: ':notempty:',
}).first() %}

There’s a chance that no entry was found, so before you start interacting with heroEntry you should make sure that first() actually returned something.
{% if heroEntry %}
    
{% endif %}

> **Comments:**
> **username_2**: Nice one Brandon, I like it more than my solution (even though I was a little proud of that recursive macro)! :)  
> **username_1**: @username_2 Hah, your solution is great too! Just thought it was worth mentioning the alternative. Performance-wise it's probably a toss-up if the hero image is never more than 3 levels away, though this one will be a little more scalable if it could be a few levels deeper.  

---

