I can code a little but I'm not very good so I'm having trouble finding an approach to implement this.
I started 7 years ago from zero, I only knew HTML and CSS. I learned and mastered Rules & Views. But like 4 or 5 years ago, I ran into scenarios like this one where the existing modules didn't quite do what I needed or felt I had to do overkill/bulky-overhead workarounds with existing modules. So I learned PHP from online resources and I learned how to create custom modules for Drupal.
I highly suggest you improve your backend/coding game. Specially since Rules in D8 is barebones compared to D7.
I tried to build this in Views. The problem I encountered was that it is very difficult to iterate through the subdivision entity reference field and filter out the previous and next links.
While it's possible to programmatically solve it with Views, it feels overkill/unnecessary to do this in Views just for prev and next links. A better approach is to create prev_url
and next_url
variables for Twig. Using a preprocess function we can create and pass those variables to the appropriate template file, node.html.twig in this case.
I've put lots of comments, so you can follow and hopefully learn a thing or two.
In mytheme.theme (since this particular hook can also be used in theme, rather than creating a custom module).
/**
* Implements hook_preprocess_HOOK() for node.html.twig.
*/
function mytheme_preprocess_node(&$variables) {
$node = $variables['elements']['#node']; // obtain current page node object
if ($node->getType() == 'page') { // check it's a "page" content type
$page_nid = $node->id(); // get the current page node id
// get Chapter nids using Entity Field Query
$query = \Drupal::entityQuery('node')
->condition('type', 'chapter')
->condition('field_reference', $page_nid); // check if current page NID is set on any Chapter's reference field
$chapter_nids = $query->execute(); // returns array of Chapter nids
if (!empty($chapter_nids)) { // check we have a result
$chapter_nid = reset($chapter_nids); // Extracts the first array value, since we assume current page can only belong to one Chapter.
$chapter_node = Drupal\node\Entity\Node::load($chapter_nid); // load chapter node
$referenced_page_nodes = $chapter_node->field_reference; // get referenced nodes
foreach ($referenced_page_nodes as $key => $referenced_item) { // loop though referenced nodes
if ($referenced_item->entity) {
if ($node->id() == $referenced_item->entity->id()) { // check if current page nid equals referenced nid
$prev_key = $key - 1; // we'll use these keys to access prev/next array values
$next_key = $key + 1;
if (!empty($referenced_page_nodes[$prev_key])) { // check if previous key exists
$prev_url = $referenced_page_nodes[$prev_key]->entity->toUrl()->toString(); // get prev URL
$variables['prev_url'] = $prev_url; // creates prev_url variable in node.html.twig
}
if (!empty($referenced_page_nodes[$next_key])) { // check if next key exists
$next_url = $referenced_page_nodes[$next_key]->entity->toUrl()->toString(); // get next URL
$variables['next_url'] = $next_url; // creates next_url variable in node.html.twig
}
break; // since we found it, exit from loop as no point in continuing to loop through.
}
}
}
}
}
}
Note: Rename field_reference
(2 places) to the machine name of your actual reference field in Chapter content type.
In mytheme/templates/node.html.twig, you can place them after the {{ content }}
part
{% if prev_url is not empty %}
<span><a href="{{ prev_url }}">{{ 'Previous page'|t }}</a></span>
{% endif %}
{% if next_url is not empty %}
<span><a href="{{ next_url }}">{{ 'Next page'|t }}</a></span>
{% endif %}