2

Update: Now I know the cause of my problem, I have appended to the original question title to try and help other people stumbling across the same issue.


I have a pending support ticket open with P&T on this, but just wondering if anyone else has had a similar experience and might be able to point me in the right direction.

I have a development site running happily on Craft 2.6.3013. As a first foray into Craft 3 I thought I would upgrade it to Craft 3 in a dedicated folder and DB of my local setup.

All seemed to go fine. I worked through and eliminated deprecation errors in my 2 well developed templates.

But one of the templates utilises a Matrix field with 2 block types -- subsection and item -- and only subsection rows are publishing.

The 20 rows originally in the field (in its singles entry) are all there in the back end, and their respective types show up as they should there: 5 for subsection and 15 for item.

But a simplified front end loop of:

<ul> {% for row in entry.timeline.all() %} <li>{{ row.type }}</li> {% endfor %} </ul>

…only produces the following outcome:

<ul> <li>subsection</li> <li>subsection</li> <li>subsection</li> <li>subsection</li> <li>subsection</li> </ul>

5
  • With devMode set to true, what does this print: {{ dump(entry.timeline.all()) |raw }}?
    – Paul
    Commented Apr 12, 2018 at 13:53
  • I get a super long array with 5 items: array(5) { [n]=> … { … } }. ~87k characters in total. I'm not sure what I should be seeing but it's internal structure looks a bit questionable. There is lots of nested "_nextElement" and various instances of *RECURSION*. Commented Apr 12, 2018 at 17:17
  • Applying this dump to my Craft 2.6 instance, which I still have, I can see *RECURSION* in there too, so I guess that is not a cause for concern. Crucially though, the array is 20 items as I would expect. Commented Apr 12, 2018 at 17:31
  • Strange. Can’t really tell you more without seeing Craft and code ...
    – Paul
    Commented Apr 12, 2018 at 17:34
  • Sure. Thanks for the debugging suggestion. Good to see the internal workings! I have sent my db to P&T. Think they are looking at it. Commented Apr 12, 2018 at 17:36

1 Answer 1

1

Turns out my issue is because I am running 2 loops through entry.timeline:

  1. A subset of the field with only subsection blocks to generate a table of contents
  2. The entire field contents with a mixture of both subsection and item block types.

Craft 2 was totally OK with me defining a subset and then looping through the entire set, but with Craft 3, if the subset is defined first, it seems to persist when the second loop runs, even if the scope of the second loop is defined differently.

So my current solution is to have a template structured like this:

{# Fetch the entire set first even though it will run second #}
{% set timelineItems = entry.timeline.all() %}

{# Fetch the subset second even though it will run first #}
{% set tocItems = entry.timeline.type('subsection').all() %}

{% for item in tocItems %}
    {# do subsetted ToC stuff #}
{% endfor %}

{% for row in timelineItems %}
    {# do entire timeline stuff #}
{% endfor %}

See https://github.com/craftcms/cms/issues/2160 for more background, and cloning element queries in the docs.

4
  • Just to clarify: that's the normal and expected behavior since entry.timeline is a reference to an object of type ElementQuery. When you change certain criterias/properties of that object it won't magically reset them afterwards. You would need to clear the property Commented Apr 17, 2018 at 20:39
  • Ok, thanks Robin. Because it was a non-issue in Craft 2 it was hard for the uninitiated like me to see that it would be an issue in Craft 3. Is this behaviour explicitly mentioned in the docs? How does one "clear the property"? Commented Apr 17, 2018 at 22:11
  • I now understand that I was running into this issue: github.com/craftcms/cms/issues/2160. And that there is a clone() function to address it. Commented Apr 17, 2018 at 22:16
  • 1
    I now see that this issue is well explained in the 'Changes in Craft 3' section of the Docs under cloning element queries. Easy to miss if you don't know what you are looking for, which is kind of inevitable with a complex product. Commented Apr 18, 2018 at 8:20

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.