Answers.Body: <p>The <code>descendants</code> of an element include anything nested within it, regardless of depth.</p>
  <p>I believe what you want is <code>children</code>:</p>
  <pre><code>{% set topLevelComments = craft.entries()
    .section('articleComments')
    .relatedTo(entry)
    .level(1) %}
  
  {% macro renderComments(comments) %}
    &lt;ul&gt;
      {% for comment in comments %}
        &lt;li&gt;
          &lt;p&gt;{{ comment.comment }}&lt;/p&gt;
  
          {% set children = comment.children.eagerly().all() %}
  
          {% if children is not empty %}
            {{ _self.renderComments(children) }}
          {% endif %}
        &lt;/li&gt;
      {% endfor %}
    &lt;/ul&gt;
  {% endmacro %}
  
  {% import _self as comments %}
  
  {{ comments.renderComments(topLevelComments) }}
  </code></pre>
  <p>There is no need to manually define an eager-loading map—this revised example uses Craft 5’s <a href="https://craftcms.com/docs/5.x/development/eager-loading.html#lazy-eager-loading" rel="nofollow noreferrer">lazy eager-loading</a> feature. (In previous versions, you may need to call <code>.with([['children.children.children']])</code> for as many levels you expect comments to be nested!)</p>
  <h3>Bonus</h3>
  <p>If you were to display a form to add replies, you can test whether it exceeds the section’s &quot;Maximum Levels&quot; setting:</p>
  <pre><code>{% set section = comment.section %}
  
  {% if comment.level &lt; section.maxLevels %}
    &lt;form&gt;
      {# ... #}
    &lt;/form&gt;
  {% endif %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-06-04T20:43:44.153Z
Answers.Text: Thank you! of course, that was the reason. One more question. I got an error that the eagerly method does not exist. Do you know why? As far as I can see in the docs, this should work?
Answers.UserDisplayName: smaniren
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-06-06T17:55:32.523Z
Answers.Text: Without seeing the entire template in its final state, I can't say for sure. This was added in Craft 5, which the title suggests you're using… but the method doesn't exist on “element collections,” which can be returned by `comment.children`.
  
  Worth trying the `children.children.children` eager-loading map (and removing `.eagerly()` temporarily) to make sure the change from `descendants` works in isolation!
Answers.UserDisplayName: August Miller
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-06-04T20:09:40.857Z
Answers.LastActivityDate: 2024-06-04T20:09:40.857Z
Answers.UserDisplayName: August Miller
Body: <p>I'm trying to display my nested comments. I've created 7 test-comments:</p>
  <pre><code>ID   Parent ID   Comment    Descendants Count   Level
  785  N/A         test 1     6                   1
  788  785         test 2     5                   2
  791  788         test 3     4                   3
  794  791         test 4     3                   4
  797  794         test 5     2                   5
  800  797         test 6     1                   6
  803  800         test 7     0                   7
  </code></pre>
  <p>As you can see &quot;test 1&quot; is parent of &quot;test 2&quot;, &quot;test 2&quot; is parent of &quot;test 3&quot; and so on.</p>
  <p>My goal is to display the Comments like this:</p>
  <pre><code>|test 1
    |-test 2
      |-test 3
        |-test 4
          |-test 5
            |-test 6
              |-test 7
  </code></pre>
  <p>but what i get is this:</p>
  <pre><code>|test 1
    |-test 2
      |-test 3
      | |-test 4
      | | |-test 5
      | | | |-test 6
      | | | | |-test 7
      | | | | |-test 7
      | | | |-test 6
      | | |   |-test 7
      | | |   |-test 7
      | | |-test 5
      | |   |-test 6
      | |   | |-test 7
      | |   | |-test 7
      | |   |-test 6
      | |     |-test 7
      | |     |-test 7
      | |-test 4
      |   |-test 5
      |     |-test 6
      |     | |-test 7
      |     | |-test 7
      |     |-test 6
      |       |-test 7
      |       |-test 7
      |   |-test 5
      |     |-test 6
      |     | |-test 7
      |     | |-test 7
      |     |-test 6
      |       |-test 7
      |       |-test 7
      |-test 3
        |-test 4
        | |-test 5
        | | |-test 6
        | | | |-test 7
        | | | |-test 7
        | | |-test 6
        | |   |-test 7
        | |   |-test 7
        | |-test 5
        |   |-test 6
        |   | |-test 7
        |   | |-test 7
        |   |-test 6
        |     |-test 7
        |     |-test 7
        |-test 4
          |-test 5
          | |-test 6
          | | |-test 7
          | | |-test 7
          | |-test 6
          |   |-test 7
          |   |-test 7
          |-test 5
            |-test 6
            | |-test 7
            | |-test 7
            |-test 6
              |-test 7
              |-test 7
  </code></pre>
  <p>As you can see, the macro works for the first 2 levels. but after that it somehow repeats some levels.</p>
  <p>Here is my code:</p>
  <pre><code>{# select only the top comments --&gt; only id 785 in this case #}
  {% set topLevelComments = craft.entries()
      .section('articleComments')
      .relatedTo(entry)
      .with(['descendants'])
      .level(1) %}
  
  
  {# Define a macro to render comments recursively #}
  {% macro renderComments(comments) %}
      &lt;ul&gt;
          {% for comment in comments %}
          {% set level = (comment.level - 1) * 20 %}
              &lt;li&gt;
                  &lt;div style=&quot;margin-left:{{level}}px&quot; class=&quot;border flex gap-3&quot;&gt;
                      &lt;p&gt;{{ comment.comment }}&lt;/p&gt;
                  &lt;/div&gt;
  
                  {% if comment.getHasDescendants()%}
                      {{ _self.renderComments(comment.getDescendants().all()) }}
                  {% endif %}
  
              &lt;/li&gt;
          {% endfor %}
      &lt;/ul&gt;
  {% endmacro %}
  
  {% import _self as comments %}
  {{ comments.renderComments(topLevelComments) }}
  
  </code></pre>
  <p>has anyone an idea where i did something wrong?</p>
  
Tags: <macro><craft5><nested>
Title: Problem with recursive macro descendants in craft 5
ThreadText: # Problem with recursive macro descendants in craft 5
  
  (Asked by: username_0 on 2024-06-04)
  
  I'm trying to display my nested comments. I've created 7 test-comments:
  
  ```
  ID   Parent ID   Comment    Descendants Count   Level
  785  N/A         test 1     6                   1
  788  785         test 2     5                   2
  791  788         test 3     4                   3
  794  791         test 4     3                   4
  797  794         test 5     2                   5
  800  797         test 6     1                   6
  803  800         test 7     0                   7
  
  ```
  
  As you can see "test 1" is parent of "test 2", "test 2" is parent of "test 3" and so on.
  
  My goal is to display the Comments like this:
  
  ```
  |test 1
    |-test 2
      |-test 3
        |-test 4
          |-test 5
            |-test 6
              |-test 7
  
  ```
  
  but what i get is this:
  
  ```
  |test 1
    |-test 2
      |-test 3
      | |-test 4
      | | |-test 5
      | | | |-test 6
      | | | | |-test 7
      | | | | |-test 7
      | | | |-test 6
      | | |   |-test 7
      | | |   |-test 7
      | | |-test 5
      | |   |-test 6
      | |   | |-test 7
      | |   | |-test 7
      | |   |-test 6
      | |     |-test 7
      | |     |-test 7
      | |-test 4
      |   |-test 5
      |     |-test 6
      |     | |-test 7
      |     | |-test 7
      |     |-test 6
      |       |-test 7
      |       |-test 7
      |   |-test 5
      |     |-test 6
      |     | |-test 7
      |     | |-test 7
      |     |-test 6
      |       |-test 7
      |       |-test 7
      |-test 3
        |-test 4
        | |-test 5
        | | |-test 6
        | | | |-test 7
        | | | |-test 7
        | | |-test 6
        | |   |-test 7
        | |   |-test 7
        | |-test 5
        |   |-test 6
        |   | |-test 7
        |   | |-test 7
        |   |-test 6
        |     |-test 7
        |     |-test 7
        |-test 4
          |-test 5
          | |-test 6
          | | |-test 7
          | | |-test 7
          | |-test 6
          |   |-test 7
          |   |-test 7
          |-test 5
            |-test 6
            | |-test 7
            | |-test 7
            |-test 6
              |-test 7
              |-test 7
  
  ```
  
  As you can see, the macro works for the first 2 levels. but after that it somehow repeats some levels.
  
  Here is my code:
  
  ```
  {# select only the top comments --> only id 785 in this case #}
  {% set topLevelComments = craft.entries()
      .section('articleComments')
      .relatedTo(entry)
      .with(['descendants'])
      .level(1) %}
  
  {# Define a macro to render comments recursively #}
  {% macro renderComments(comments) %}
      <ul>
          {% for comment in comments %}
          {% set level = (comment.level - 1) * 20 %}
              <li>
                  <div style="margin-left:{{level}}px" class="border flex gap-3">
                      <p>{{ comment.comment }}</p>
                  </div>
  
                  {% if comment.getHasDescendants()%}
                      {{ _self.renderComments(comment.getDescendants().all()) }}
                  {% endif %}
  
              </li>
          {% endfor %}
      </ul>
  {% endmacro %}
  
  {% import _self as comments %}
  {{ comments.renderComments(topLevelComments) }}
  
  ```
  
  has anyone an idea where i did something wrong?
  
  **Tags:** macro, craft5, nested
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-06-04. Score: 1 | Accepted answer
  
  The `descendants` of an element include anything nested within it, regardless of depth.
  
  I believe what you want is `children`:
  
  ```
  {% set topLevelComments = craft.entries()
    .section('articleComments')
    .relatedTo(entry)
    .level(1) %}
  
  {% macro renderComments(comments) %}
    <ul>
      {% for comment in comments %}
        <li>
          <p>{{ comment.comment }}</p>
  
          {% set children = comment.children.eagerly().all() %}
  
          {% if children is not empty %}
            {{ _self.renderComments(children) }}
          {% endif %}
        </li>
      {% endfor %}
    </ul>
  {% endmacro %}
  
  {% import _self as comments %}
  
  {{ comments.renderComments(topLevelComments) }}
  
  ```
  
  There is no need to manually define an eager-loading map—this revised example uses Craft 5’s [lazy eager-loading](https://craftcms.com/docs/5.x/development/eager-loading.html#lazy-eager-loading) feature. (In previous versions, you may need to call `.with([['children.children.children']])` for as many levels you expect comments to be nested!)
  
  ### Bonus
  
  If you were to display a form to add replies, you can test whether it exceeds the section’s "Maximum Levels" setting:
  
  ```
  {% set section = comment.section %}
  
  {% if comment.level < section.maxLevels %}
    <form>
      {# ... #}
    </form>
  {% endif %}
  
  ```
  
  > **Comments:**
  > **username_0**: Thank you! of course, that was the reason. One more question. I got an error that the eagerly method does not exist. Do you know why? As far as I can see in the docs, this should work?  
  > **username_1**: Without seeing the entire template in its final state, I can't say for sure. This was added in Craft 5, which the title suggests you're using… but the method doesn't exist on “element collections,” which can be returned by `comment.children`.  Worth trying the `children.children.children` eager-loading map (and removing `.eagerly()` temporarily) to make sure the change from `descendants` works in isolation!  
  
  ---
  
  