1

issue is an entry that has a matrix field named contents, whose blocks have an entries field named works, and the related works channel has an entries field named authorPeople.

Issue 1's contents consists of 2 blocks: A 'regular' section and an 'alumni' section. On the cover page, I loop through the blocks. For each block, I get the entries related to their authors, so that I'm outputting entries sorted by author last name, where some authors have more than one entry associated:

{% set contributors = craft.entries({
    section: 'contributors',
    relatedTo: { sourceElement: block.works, field: "authorPeople" }
}) %}

{% set articles = craft.entries({
    section: 'works',
    relatedTo: contributors
    order: 'lastName'
}) %}

That works fine, because I've got access to block.works. Any optimization tips are welcome :)

On the individual entry page, I want to getPrev and getNext entries spanning both blocks. So if you're at the last entry in the 'regular' section, your next link is the first entry in the 'alumni' section. And if you're on the first entry in the 'alumni' section, your prev link is the last entry in the 'regular' section. The last entry in the last section won't return a next link, so I can code in a link to another page, and the first entry in the first section won't return a previous link, so I can code in a link to the cover page.

Without having to loop through the blocks, how can I get that? Trying to order by issue.contents doesn't seem to work.

  • By “individual entry page” you mean for a Works entry, right? Considering it’s possible to relate the same Works entry from multiple Issues entries, how does the Works entry know which Issues entry the navigation should be scoped to? – Brandon Kelly May 17 '16 at 19:34
  • That's right. I've got a handle on that here: {% set issue = craft.entries.section('issues').slug( craft.request.getSegment(2) ).first() %}. That's what I'm attempting to use for issue.contents. – Mark J. Reeves May 17 '16 at 20:20
3

You can get all of the works entries related to your contents Matrix field like so:

{% set works = craft.entries({
    relatedTo: { sourceElement: issue, field: 'contents.works' }
}) %}

They will most likely be out of order though. We can control that with the order parameter.

If you enable Dev Mode and look at the resulting SQL query in your browser console, you will see these two tables getting joined into it:

LEFT JOIN `craft_relations` `sources1` ON (sources1.targetId = elements.id)
LEFT JOIN `craft_matrixblocks` `target_matrixblocks1` ON target_matrixblocks1.id = sources1.sourceId

So we can pass in an order param that tells MySQL to order the entries by the block order first and their relation order second:

{% set works = craft.entries({
    relatedTo: { sourceElement: issue, field: 'contents.works' },
    order: 'target_matrixblocks1.sortOrder, sources1.sortOrder'
}) %}

Now you’ve got all of the Works entries in the proper order, and you can pass them into getPrev() and getNext():

{% set prevEntry = entry.getPrev(works) %}
{% set nextEntry = entry.getNext(works) %}
  • Yes! Thank you! I swapped lastName for sources1.sortOrder so that they're sorted by author last name within each block. Works great. – Mark J. Reeves May 18 '16 at 13:26

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.