1
  1. I use a view to display a list of books.
  2. The view has three pages: /books/title, /books/date, and /books/popularity.
  3. The pages are essentially the same with different sort criteria.
  4. The pages use a contextual filter to select books by topic based on a taxonomy.
  5. The contextual filter is set to use the query parameter topic when the filter value is not in the URL.
  6. Each page of the view includes a Drupal menu block with the items "By Title", "By Date", and "By Popularity" and links /books/title, /books/date, and /books/popularity.
  7. If I invoke /books/title?topic=5 (where 5 is the tid for the "health" topic)
    • A list of health books is correctly displayed.
    • The "By Title" <li> element in the menu is given the active and active-trail classes by the menuing system (which allows the use of CSS to highlight the active menu entry on-screen).
  8. When I'm at /books/title?topic=5 and click the "By Date" menu entry, /books/date is invoked, so the topic id 5 is not passed to the "By Date" view (unsurprisingly), resulting in a list of all books sorted by date instead of just health books sorted by date.

QUESTION:

How can I pass the contextual filter value (5 in this example) from one page to another via the menu? For example, if at /books/title?topic=5 I click "By Date", I want to go to /books/date?topic=5. How can I set that up?

NOTES

  1. This post is similar to an earlier one where I asked how to get the value coming through the contextual filter. I solved that. There is a twig variable available, in this case, {{ arguments.field_topic_target_id }}.
  2. I used this twig value to rig up my own menu. But having done that, I find that I need the goodness of the Drupal menuing system, both because it makes it easy for editors to change menu items and because it handles the addition of the active and active_trail classes to the proper menu entry.
  3. I have read and tried dozens of approaches to passing the filter value received on to another page via a menu, but none have been effective.

BONUS

Assuming this problem can be solved, I'd really like to use clean URLs. So instead of /books/title?topic=5 I want to use /books/title/5. This works to correctly display a list of health books sorted by title, but when used, the menuing system does NOT set the active and active_trail classes on the active menu <li>, which I need it to do.

1

The "connected" exposed sorting criteria is implemented in the Facets module and Search API. Here's a tutorial that can help get you started: Creating a Faceted Search View in Drupal 8 using the Search API Modules


Before you start testing new modules maybe the "ordinary" Exposed Sort criteria in Views can help. Create only one Page display, but add all 3 Sort criteria you want and Expose them. You can use the Expose form in Block to show those options in some region of your theme instead of above the results.

The Better exposed filters module allows you change the widgets from drop-downs to Radio buttons or links. You can also rewrite the filter options to make them more relevant for your cases, and combine the "sort order" with "sort by".

Having an exposed form block can serve like Menu items, showing the user what has been selected, which is what the active menu trail does.


To clean up the URLs there is the Query Parameters To URL module but it's still being ported to Drupal 8. (Help advance it if you can.) Without it I guess you can set up some path redirects manually, although it might be tedious if you have a lot of combinations to cover. You can do that in .htaccess or with the Redirect module.


Yet another approach I can think of is the Views Global Filter module. You might use the "topic" globally, then sort links might work with menu trails (I haven't tried it).

  • Thanks for these many suggestions, @prkos. It will take me a while to digest them all. It seems good to stick with a real Drupal menu because we're trying to match the style used in other places in the site where real menus are used and their behavior is consistent. But I may be able to get around any issues with some work. – Marshall Morrise Apr 22 at 17:56

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.