0

I use the D8 book module to manage magazines and their articles.

In the node--magazine.html.twig template for a magazine, I use the built-in book_navigation block to add a table of contents. This is done by drupal_block("book_navigation", {block_mode: "book pages"}). Works fine.

For certain "featured" articles in the table of contents, I want to display an image. I use MYTHEME_preprocess_book_tree(&$variables) to add the image url to the items array in $variables. I've sub-themed book-tree-html.twig to get the image url from the items array and include the image in the table of contents. Works fine.

BUT, I need to know in node--magazine.html.twig whether there are any featured articles in the table of contents to present a proper heading on the page.

QUESTION: What is the best way to pass a variable from THEME_preprocess_book_tree() to node--magazine.html.twig? It's not a direct connection. Getting preprocess variables in book-tree.html.twig is easy, but I need to pass a variable through to node--magazine.html.twig, where the book tree is inserted.

What I have tried:

  • In the book-tree.html.twig template, if there is a featured article, I add a hidden "featured-article" label to the html and then in the magazine template, I test for its presence via {% if "featured-article" in <rendered block html> %}. This works, but it feels unsavory.

  • In MYTHEME_preprocess_book_tree(), I add $variables['featured'] = $feature_count; and in the magazine template I {{ dump(featured) }}. This doesn't work. I just get NULL. I'm not sure what--if any--connection there is between the $variables array available in the preprocess hook and variables available in the magazine template.

  • In MYTHEME_preprocess_book_tree(), I could set a global variable and then in the magazine template, call a custom twig extension to check the value of that variable. I haven't tried this yet, but it seems like this should work. Just seems like there should be a more elegant way.

  • the book-tree.html.twig uses macro similar to menu.html.twig. see Adding more variables to menu for use in menu.html.twig – usernameabc Apr 1 at 19:35
  • I think your second approach should work. If you are preprocessing in THEME_preprocess_book_tree, your $variables array should be available for use in book-tree.html.twig. If your preprocess function is otherwise working for this template, are you sure the issue isn't with dump()? That sounds silly, but I've had issues with it. Have you tried just setting the values and checking if that works? Does the $variables array from that preprocess function otherwise work? Just trying to figure out where the issue is coming from here. – aburke626 Apr 1 at 21:52
  • Thanks @usernameabc. I read the post and tried everything I could think of, but no success. The situation may be different in that I have a value in the preprocess function for the book_navigation block and I want to get that value--not in the twig template for the book_navigation block--but in a twig template into which the book_navigation block is inserted. I just can't seem to find a connection between the $variables array available in the book_navigation preprocess hook and the array of values that is available in the template where the block is inserted. – Marshall Morrise Apr 1 at 22:15
  • Thanks, @burke626. I can get variables set in THEME_preprocess_book_tree just fine in book-tree.html.twig. Unfortunately, that's not where I need to know if there was at least one featured article. I need to know that in the node--magazine.html.twig template, into which I insert the book_navigation block via {% drupal_block("book_navigation", {block_mode: "book pages"}) %}.I'll edit my question to clarify. – Marshall Morrise Apr 1 at 22:21
1

After a lot more digging and trying things without success, I ended up solving the problem of passing a value from a block's preprocess hook to a twig template where the block is inserted as per my third option above. Here's what I did:

  • Follow the instructions at http://www.tothenew.com/blog/overview-of-twig-extentions-in-drupal-8 to create a twig extension. This wasn't very difficult, especially since I had already created a custom module. I just had to create a MYMODULE.services.yml file and a TwigExtension.php file as instructed.

  • In the twig extension file, create functions setTwigValue($name, $value) and getTwigValue($name) using the php $GLOBALS array for storage. Again, the above-mentioned instructions made this pretty easy.

  • In the preprocess_book_tree hook, count the number of feature articles and then save the count by calling

    Drupal\MYMODULE\TwigExtension::setTwigValue('feature_count', $feature_count);

  • In the node--magazine.html.twig template, get the saved value using

    {% set feature_count = getTwigValue('feature_count') %}

I'm happy to learn of better/safer ways to accomplish what I've done. But at least it works and it's pretty clean.

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.