1

I have a matrix field with with multiple types. In a template I want to loop through all of the entries of that matrix field as you normally would. However, I also want to access a bit of data from a specific type and I can not figure out how to do it. Very frustrating. Definitely would have been a no brainer to do in craft 2.5.

The matrix field has a type of "Instructor" which is an entry type. The entry has a field of "FullName".

So I want to say, if there is an entry type of Instructors in the matrix field, then output the full name of each entry selected in the matrix field of type "Instructor".

I've tried various methods based on the matrix blocks documentation and nothing works. The closest I get is the ID of the matrix field entry. Here is one example that should explain what I'm attempting to do.

  {% set classBlocks = entry.classBlocks %}
  {% if classBlocks|length %}
    {% set instructors = clone(classBlocks).type('instructors').all() %}
    by <strong>
      {% for instructor in instructors %}
        {% if not loop.first %}, {% endif %}
        {{ instructor.fullName }}
      {% endfor %}
    </strong>
  {% endif %}

Is this even possible? Seems pretty simple. At least in craft 2.5 I could have just looped through the matrix field and if the type was 'instructors' loop through the instructor entries outputting their full name.

  • Everything is possible, but the wording of your question makes it difficult to understand your setup, as you are using the phrase "entry type" when you could mean "block type", or possibly "field type". These are three separate things. Matrix blocks cannot contain "entry types". Consider editing your question for clarity between block type handles and field handles. – James Smith Sep 6 '20 at 10:15
1

Here's how I would approach this...

{% set classBlocks = entry.classBlocks.all() %}

{% if classBlocks | length %}
    {% set instructors = classBlocks | filter(block => block.type == 'instructors') %}
    by <strong>{{ instructors | map(instructor => instructor.fullName) | join(', ', ', and ') }}</strong>
{% endif %}

We're using several filters here to achieve what I think you're trying to achieve:

  • | filter is used to filter just the instructor blocks out of all your class blocks; this saves us from having to do the cloning and extra query mess and is more performant.
  • | map is used to take our array of instructor blocks and return an array containing just their names.
  • | join is used to take the array of names and create a nice readable list (I find it cleaner than doing the loop checking like you're doing) - e.g. "Bob, Matt, and Susy"

Let me know in the comments if you have any questions or if I'm not understanding the question correctly!

  • Ok so first of all thank you. It didn't work. Same think is happening that i've gotten before. nothing but "by" is output and if I add {{instructors|join(' | ')}} to see what's in the instructors array I get the ID of the entry field in the matrix type. This seems to be a bug with craft. The documentation is either incorrect or this is a bug. – jpwdesigns Sep 4 '20 at 16:34
  • If I do this: ``` {% if classBlocks | length %} {% set instructors = classBlocks | filter(block => block.type == 'instructors') %} {% for instructor in instructors %} {{ instructor.instructorEntries|join(' | ') }} {% endfor %} {% endif %} ``` I get the title's of the entries I want. Nice right? However I want the fullName field of those entries – jpwdesigns Sep 4 '20 at 16:53
  • If I try to step in to access the fullName field of the entry, I get a date time error. craft Object of class DateTime could not be converted to string. That just makes no sense at all. I've given up and approached this differently. – jpwdesigns Sep 4 '20 at 17:14

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.