1

I think I have been staring at this problems too long and I need a kick in the right direction...

Here is what I have (the content modeling is a tad wonky but this is what we're dealing with):

Clients Channel

  • Work Samples Matrix Field (1 matrix block inside the matrix field)
    • Category matrix block field pulling from work categories
    • Assets matrix block field to upload images
    • Table matrix block field to enter youtube ID's

This is what I need to do:

When a category is selected by a user I take the user to a category listing page that contains all clients (from the Clients channel) with work samples within that category (categories within the matrix block from each client in the client channel).

For example: All clients with "website" samples should be displayed on a page at http://domain.tld/category/website

What is the most efficient way to pull this off in Craft/twig?

Reading the Craft docs is getting me about 1/2 there but something in the relationships docs isn't clicking yet.

1 Answer 1

9

First you need to define the category. If your category group has the “Categories in this group have their own URLs” checkbox checked, and the URL Format is set to category/{slug}, and this is happening on the template you’ve specified in the Category Template setting, then all the stars have aligned and this step is taken care of for you automatically. The category will already be available to your template, and it will be called category.

Otherwise you will have to fetch it yourself:

{% set category = craft.categories({
    group: 'workCategories',
    slug: craft.request.getSegment(2)
}).first() %}

{% if not category %}
    {% exit 404 %}
{% endif %}

Once you have your category, you can fetch the related Clients using the relatedTo param on a craft.entries query:

{% set clients = craft.entries({
    section: 'clients',
    relatedTo: {
        targetElement: category,
        field: 'workSamples.myCategoriesField'
    }
}) %}

That’s saying: “Give me the entries in the clients channel, which are related to category (where category is the target of the relation), via the myCategoriesField sub-field of a workSamples Matrix field.” Make sense?

Once you have those client entries you can loop through them, and show their respective Matrix blocks which are related to the category:

{% for client in clients %}
    <h3>{{ client.title }}</h3>

    {% for workSample in client.workSamples.relatedTo({ targetElement: category }) %}
        {% for image in workSample.myAssetsField %}
            <img src="{{ image.url }}">
        {% endfor %}

        {% for row in workSample.myTableField %}
            {{ row.youtubeId }}
        {% endfor %}
    {% endfor %}
{% endfor %}

If there are going to be a lot of clients/Matrix blocks/assets getting looped through, it’s probably going to be a good idea to wrap the whole thing in {% cache %}...{% endcache %} tags, as there’s potential for the query count to really pile up here.

1
  • Thank you kind sir! Your explanation helped me out a ton on this (compared to the docs). I think you just gave me that "ah-ha" moment in regards to relations.
    – Paulo
    Nov 21, 2014 at 7:33

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.