1

I have entries from a section 'title' which all have an associated category 'author'. Category has an associated field 'sortName'. Essentially, I am trying to sort a bunch of books by author last name (stored in sortName).

I am trying to sort all entries in 'title' by 'author.sortName' but as they are in separate tables, I cannot make the relation without throwing an error.

Is there a way to query all entries, sort them by a category field and then loop through them?

I have everything working except the grouping which is NOT actually sorting the entries by the titleAuthor Category at all. Ideally I want it to sort by titleAuthor.sortName

Right Now I'm trying:

{% if categorySlug is defined %}
  {% set category = craft.categories.slug(categorySlug).one() %}
  {% set entries = craft.entries.section('titles')
    .relatedTo(category)
    .titleDisplayNYLA(true)
    .orderBy('titlePublicationDate DESC')
    .all()
  %}
  {% set title = category.title %}
  {% set entriesGrouped = entries|group('titleAuthor.first().title') %}
{% else %}
  {% set entries = craft.entries() 
      .section('titles') 
      .titleFeatureHome(':notempty:')
    .titleDisplayNYLA(true)
    .all()
  %}
  {% set title = 'NYLA•Tites' %}
  {% set info = craft.entries.section('titlesIndex').one() %}
  {% set entriesGrouped = entries |group('titleAuthor.title') %}
{% endif %}

{% for group in entriesGrouped  %}
  {% for category, entry in group %}
    {{entry.title}}
    {% for category in entry.titleAuthor.all() %}{{ category.title }} {% endfor %}
  {% endfor %}
{% endfor %}

2 Answers 2

1

Brandon Kelly provided two examples of how to accomplish this here:

https://github.com/craftcms/cms/issues/6010


Copying what's linked there in-case that link ever goes dead


Original Question: I have an app that let's users create quotes. When they create the quote, they choose a dealer. The dealers are in a separate section and set as a relationship field. Now, when the user is looking at a table of quotes, they cannot sort the data by that dealer field.

Answer: To do that, you’d have to join the dealer entry into the query, first:

{% set dealerField = craft.app.fields.getFieldByHandle('dealer') %}
{% set quotes = craft.entries()
  .section('quotes')
  .innerJoin('{{%relations}} dealer_relation', [
    'and',
    '[[dealer_relation.sourceId]] = [[elements.id]]',
    {
      'dealer_relation.fieldId': dealerField.id,
      'dealer_relation.sortOrder': 1
    }
  ])
  .innerJoin('{{%content}} dealer_content', '[[dealer_content.elementId]] = [[dealer_relation.targetId]]')
  .orderBy('dealer_content.title')
  .all() %}

Alternatively, you could create a Preparse field that stores the first related dealer’s title, and then order by the Preparse field instead. That would have the added benefit of making the quotes sortable by dealer in the control panel as well.

Here’s the template you would use for that field:

{%- set dealer = element.dealer.one() -%}
{{- dealer.title ?? '' -}}
1
  • any advice on the above with the further code example? It doesn't seem to be grouping by anything. I tried your code but couldn't understand how to utilize it properly. Appreciate any help!
    – Ben
    Commented Jan 20, 2022 at 17:38
1

I ended up using a preparse field from the pre-parse plugin. Was absolutely the most straightforward way.

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.