1
  1. I use the Book module to create books with chapters.
  2. When I use the default twig template node.html.twig to display a book chapter, a section titled "Book traversal links" is included, with links to the previous chapter, the next chapter, and to the book. The debugger says these links come from the book-navigation.html.twig template.
  3. Instead of the default template, I'm using a custom twig template node--chapter.html.twig to display chapters.

QUESTION:

How can I get the same book traversal links onto my custom page?

NOTES:

  1. I checked for a block containing the book traversal links that I could just insert in my twig template, but I don't see one.
  2. I have checked the $variables array in the twig template to see if maybe a list of the chapter's siblings is already there, but don't see one.
  3. I'm already using HOOK_preprocess_node(&$variables) to find the book parent book's id, so I can use it to find the chapter's siblings, if that's the way to go.

2 Answers 2

0

Alas, there is no block for this; the book navigation links are hacked on to the node view in core.

From core/modules/book/book.module:

/**
 * Implements hook_ENTITY_TYPE_view() for node entities.
 */
function book_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
  if ($view_mode == 'full') {
    if (!empty($node->book['bid']) && empty($node->in_preview)) {
      $book_node = Node::load($node->book['bid']);
      if (!$book_node->access()) {
        return;
      }
      $build['book_navigation'] = [
        '#theme' => 'book_navigation',
        '#book_link' => $node->book,
        '#weight' => 100,
        // The book navigation is a listing of Node entities, so associate its
        // list cache tag for correct invalidation.
        '#cache' => [
          'tags' => $node->getEntityType()->getListCacheTags(),
        ],
      ];
    }
  }
}

The good news is that this should work with custom templates as long as you are using the full view mode.

I have a custom node template and I still get the navigation links on my books at the bottom of the content. (Unfortunately, whether I want them there or not-- as per the above code, they are forcibly added and there is no UI to control them.)

0

You can code the book navigation into your own block.

In this case, you will need to override book_node_view() so that the nav links are not displayed twice.

This may give you an idea (not complete code, cannot be used by itself; inspired by this post):

class BookNavigationBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];
    $node = \Drupal::routeMatch()->getParameter('node');
    if (isset($node)) {
      if ($node->bundle() == 'book') {
        $build['book_navigation'] = [
          '#theme' => 'book_navigation',
          '#book_link' => $node->book,
          '#weight' => 100,
          // The book navigation is a listing of Node entities, so associate its
          // list cache tag for correct invalidation.
          '#cache' => [
            'tags' => $node->getEntityType()->getListCacheTags(),
          ],
        ];
      }
    }
    return $build;
  }

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.