1

I'm creating a dynamic side navigation where pages can choose which sidebar it wants to use. This is selected by an entries field called 'sidebar' - called in line 2.

To create this I've made a structure called 'Sidebars' with an entry for each sidebar type. Each Sidebars entry has an entries field in it which can select any number of pages.

I've got it fully working, but it's giving me deprecation errors.

Here's the working (but deprecated code on line 4): (lines 5-12 figure out whether the path includes 'whats-on' or 'who-we-are' and adds them to the path to the entry if needed).

<div>
  {% set sidebarChoice = entry.sidebar.one() %}
  {% for rel in sidebarChoice %}
    {% for sidebarEntry in rel %}
      {% set myEntryQueryUrl = sidebarEntry.url %}
      {% if 'whats-on' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/whats-on/' %}
      {% elseif 'who-we-are' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/who-we-are/' %}
      {% else %}
        {% set myEntryQueryPath = '/' %}
      {% endif %}

      <div>
        <h3>{{ sidebarEntry.title }}</h3>
        <a href="{{ myEntryQueryPath }}{{ sidebarEntry.slug}}">
        <p class="smallcontentblocks-text">{{ sidebarEntry.title }} text</p>
        </a>
      </div>

    {% endfor %}
  {% endfor %}
</div>
  • What deprecation error are you seeing? – Marion Newlevant Aug 21 at 1:09
  • I'm getting this: Looping through element queries directly has been deprecated. Use the all() function to fetch the query results before looping over them. And the error is on the line {% for sidebarEntry in rel %} But when I try {% for sidebarEntry in rel.all() %} I get the Twig Runtime Error page with the notice: Impossible to invoke a method ("all") on a string variable. – Jonathan Aug 21 at 10:34
1

You don't mention what your related entries field handle is, but remember that calling any related element (entries/assets/categories/users/tags) will require a .all() (or .one() or .ids() or one of the other query-executing methods) unless the related elements are eager-loaded. With that in mind I can't see anywhere in your code where you're executing a call to fetch the related entries from sidebarChoice, and you also seem to have a redundant inner loop. With eager-loading it might look like this:

<div>
  {% set sidebarChoice = entry.sidebar.with(['sidebar.yourRelatedEntriesHandle']).one() %}
  {% for sidebarEntry in sidebarChoice.yourRelatedEntriesHandle %}
      {% set myEntryQueryUrl = sidebarEntry.url %}
      {% if 'whats-on' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/whats-on/' %}
      {% elseif 'who-we-are' in myEntryQueryUrl %}
        {% set myEntryQueryPath = '/who-we-are/' %}
      {% else %}
        {% set myEntryQueryPath = '/' %}
      {% endif %}

      <div>
        <h3>{{ sidebarEntry.title }}</h3>
        <a href="{{ myEntryQueryPath }}{{ sidebarEntry.slug}}">
          <p class="smallcontentblocks-text">{{ sidebarEntry.title }} text</p>
        </a>
      </div>
  {% endfor %}
</div>
| improve this answer | |
  • Thanks, the related entries field handle is sidebarTitle. – Jonathan Sep 2 at 15:12
0

Thanks, the related entries field handle is sidebarTitle.

The first part of the above cleared the errors with an additional .all():

<div>
{% set sidebarChoice = entry.sidebar.with(['sidebar.sidebarTitle']).one() %}
     {% for sidebarEntry in sidebarChoice.sidebarTitle.all() %}
     {% set myEntryQueryUrl = sidebarEntry.url %}
     {% if 'whats-on' in myEntryQueryUrl %}
     {% set myEntryQueryPath = '/whats-on/' %}
     {% elseif 'who-we-are' in myEntryQueryUrl %}
     {% set myEntryQueryPath = '/who-we-are/' %}
     {% else %}
     {% set myEntryQueryPath = '/' %}
     {% endif %}

 <div>
    <h3>{{ sidebarEntry.title }}</h3>
    <a href="{{ myEntryQueryPath }}{{ sidebarEntry.slug}}">
      <p class="smallcontentblocks-text">{{ sidebarEntry.title }} text</p>
    </a>
  </div>
{% endfor %}
| improve this answer | |
  • If you eager load correctly, you won't need the .all() in {% for sidebarEntry in sidebarChoice.sidebarTitle.all() %} (that's the whole point of eager loading, to prevent extra queries). Double check your eager-loading syntax - it's possible it should just be .with(['sidebarTitle']. – James Smith Sep 4 at 14:46

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.