Editor's Note: The following was written for Drupal 7, but should work as described under Drupal 9. The one main difference is that Drupal 9 does not have a "master" view, but you could have "block" or other types of views. Just make sure you're editing the view to which you want to apply a contextual filter.
Contextual filters in Views are powerful, but getting them to work perfectly can be a nightmare. This will hopefully save some people from the headaches I had.
My goal was to have a News page that could easily be filtered to only have specific stories. I started with:
- A Taxonomy vocabulary called "Keywords"
- A "News Story" content type
- A field named "Keywords" in the News Story that is a Term Reference type linked to the Keywords taxonomy
Our news stories are imported from Mercury, and the keywords are automatically imported into the Taxonomy vocabulary.
The goal is to have a page that lists all our news stories at example.gatech.edu/news. A simple view can handle that easily. With a correctly configured contextual filter, we can add a taxonomy term to the end of the URL, and the view will automatically filter itself down to just the stories tagged with a term. Basically:
- example.gatech.edu/news will list all news stories
- example.gatech.edu/news/robotics will list all news stories with the keyword "robotics"
- example.gatech.edu/news/music will list all news stories with the keyword "music"
Neat, right? The problem is, contextual filters can be a nightmare to set perfectly.
Part 1: Create the Basic View
-
Create a new view at
Structure -> Views -> Add
. We set ours to show content of type News, sorted newest first. -
Make sure the "Create a page" box is checked, give it a URL, and set the display format to something simple like unformatted list of linked titles.
-
Save the view and head to the URL to make sure it works. Good? Let's head back and edit that view.
Part 2: Make the View Advanced!
Make sure you are using the Page display, not the master. Usually when something isn't working, it's because I was not editing the page view.
-
Open the Advanced menu on the right if it isn't already.
-
Select Add next to Contextual filters.
-
Check Content: Has taxonomy term ID in the pop-up and Apply.
On the next page, under "When the filter value is NOT in the URL:"
This controls what the view does when there's nothing added to the end of the view's URL - i.e., in our case, what will show at http://example.gatech.edu/news
. The options include:
- Display all results for the specified field - Shows everything that matches the view's base filter. This is what makes our default news page show all stories.
- Provide default value - Lets you chose a default tag if you want a subset shown.
- Show "Page not found."
- Display a summary.
- Display contents of "No results found."
- Display "Access Denied."
The next section is "When the filter value IS in the URL or a default is provided:" We used two options:
- Override title - this lets you change the default title. We entered "News stories tagged with %1", which will take the term in the URL and substitute it for the %1. So if you are on example.gatech.edu/news/music, the title will be "News stories tagged with music."
- Specify validation criteria - this is the tricky part. Check this, then:
- Set Validator to "taxonomy term."
- Select the "Keywords" vocabulary.
- Set Filter value type to "Term name converted to Term ID."
- Check "Transform dashes in URL to spaces in term name filter values."
- Set Action to take if filter value does not validate to "Display a summary."
Finally, save the filter, then save the view.