1

Channels: Photographers Photos - entries field handle "photographers" - categories field handle "category"

url structure where segment 2 is the photographer slug and segment 3 is the photo category slug:

domain.com/photographers/john-doe/food

On the photographers detail page I need to pull up the photos entries that are related to that photographer and in the category determined by segment 3

Set at the top of the page and used in a couple of different spots

{# set segment variables so we can use shorthand #}
{% set segment_2 = craft.request.getSegment(2) %}
{% set segment_3 = craft.request.getSegment(3) %}

{# get related photo entries #}
{% set photos = craft.entries.section('photos').relatedTo(entry) %}

Then where I want the photos to display I have the following code which outputs 2 entries from the photos channel. These are both related to the current photographer but in different categories. Only the one entry that is both related to the photographer and the current category should be output.

  {# set currentCategory to category id from segment 3 #}
  {% set currentCategory = craft.categories.slug(segment_3).first() %}

  {% set photos = photos.relatedTo(currentCategory.id) %}

  {% for photo in photos %}
    {{ photo.title }} <br>
  {%endfor %}

I'm not sure how to combine and filter these relations. Please advise.

2

We’ve built a plugin called Router that solves exactly this use case.

For the URL structure you described – domain.com/photographers/john-doe/food – this can be solved by the following configuration for the Router plugin:

/* config/router.php */

return [
  'rules' => [

    // URI pattern with named subpatterns
    '<placeholder:photographers>/<photographerEntry:{slug}>/<foodCategory:{slug}>' => [

      // array of filters that are activated when
      // the key matches a subpattern variable declared in
      // the route's regular expression
      'criteria' => [
        'placeholder' => 'section:photographerPhotos', // Base section
        'photographerEntry' => 'entry:photographers',  // Find slug in section        
        'foodCategory' => 'category:food',  // Find slug in group
      ],

      // template file
      'template' => 'photographerPhotos/_entry',
    ],

  ]
];

And in the template:

{# photographerPhotos/_entry #}

{{ entries }} {# array of photos (related to both the photographer and food category) #}
{{ photographerEntry }} {# photographer Entry object #}
{{ foodCategory }} {# food Category object #}
1

So I solved this with the following code:

  {# 
   // loop through related photos
   // and loop through related category photos
   // set photoId = to common id in both loops
  #}
  {% set photoId = "" %}
  {% for photo in photos %}
    {% for catPhoto in photos.relatedTo(currentCategory.id) %}
      {% if photo.id == catPhoto.id %}

        {% set photoId = catPhoto.id %}
        {# {% set photoId = photoId|merge([catPhoto.id]) %} #}
      {% endif %}
    {% endfor %}
  {% endfor %}

Then the following outputs the entry in question

{% for photo in craft.entries.section('photos').id(photoId).find() %}
  // output entry related to photographer and category here
{% endfor %}

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.