In February, I built a WordPress plugin that allowed users to browse blogs by choosing a top-level category in one select box and then having whatever top-level category they select populate a second select box with the subcategories of that top-level category. I decided I would re-create that functionality as a Drupal 8 module.
My new Drupal 8 creates a block that pulls in the category and subcategory browsing form, and the module also creates a config page that allows admins to choose which taxonomy they want to use as the top-level category in the browsing form. On this website, I enabled the module and placed the block at the top of the left-hand sidebar. The categories and subcategories in this example just contain dummy content, but it gives you an idea of how the module works.
The code for the module is here: https://github.com/mckinzie25/tag_subtag_browsing. Lots of Drupal 8 module development tutorials are starting to percolate around the web now, so what I will focus on here is just how I used routing to create an admin menu link and form redirects in the module code.
One of the most notable changes in Drupal 8 is that configuration information is contained in YAML files, and pages are defined not by hook_menu but by routes. For my Multi-Level Category Browsing module, I wanted to create a link to its admin screen from the Search and Metadata section of the Configuration page. This required two YAML files, one to create the page for the admin screen, and one to link to it from the configuration page.
tag_subtag_browsing.settings: path: '/admin/config/browsing/tag_subtag_browsing' defaults: _form: 'Drupal\tag_subtag_browsing\Form\TagSubtagBrowsingSettingsForm' _title: 'Better Browsing With Tags and Subtags Configuration Form' requirements: _permission: 'administer site configuration'
tag_subtag_browsing.settings: title: 'Tag Subtag Browsing Configuration Form' description: 'Select the taxonomy used by the Better Browsing With Tags and Subtags Form.' parent: system.admin_config_search route_name: tag_subtag_browsing.settings weight: 10
The first YAML file creates the admin page by defining:
- a route (the first line of the file)
- a path for the route
- the namespace of the form to be used
- the title
- and permissions.
Notice that unlike in Drupal 7, the route is what will be used to refer to the page everywhere else, not the path. This means the path can be changed later without messing anything else up.
The second YAML file creates the menu link. I wanted this link to appear on the Configuration page under the Search menu, so to do that I had to find the right "parent" route. This can be a little tricky. When the question of how to find the correct parent route came up at DrupalCon, one instructor suggested, "Google is your friend." Well, if you found this page through Google, then he was right! Routes for all the items on the Configuration page are listed in /core/modules/system/system.routing.yml. To find the route for the Search menu, I just looked for "Search and metadata" in this YAML file, which gave me the route system.admin_config_search. The Configuration page now shows a link to my page, with the title and description given in the code for tag_subtag_browsing.links.menu.yml above. Here is a screenshot of the link:
Other important YAML files can be found in /core/modules to help you find the routes you need. For example, when the user submits the category and subcategory browsing form to go to a subcategory page, the script in /modules/custom/tag_subtag_browsing/src/Form/TagSubtagBrowsingForm.php uses the setRedirect() method of the $form_state object to send the user to the right page. But the setRedirect() method requires the proper route to do that, so I had to find the route for taxonomy pages. I found this by going to /core/modules/taxonomy/taxonomy.routing.yml and finding "entity.taxonomy_term.canonical" as the route for taxonomy term pages.
Sifting through YAML files to find routes may take some getting used to, but if you do a grep-like search on /core/modules for a path or partial path (e.g., "/taxonomy/term") or a title (e.g., "Search and metadata"), you should be able to find what you are looking for.