Taxonomy Menus for Custom Views
Note: If you’re looking to just output a list of taxonomy terms that link to a custom view, please see PHP Code to Output a List of Terms Linked to a Custom View. If you need actual Drupal menu items for each term in a vocabulary to point to a custom view, please read on.
The taxonomy_menu module is a great module for automatically building (and keeping in sync) a menu of taxonomy terms. The taxonomy terms, by default, point to the default taxonomy listing. In some cases this is just what you want, but more often than not, you’ll probably be creating a custom View. Taxonomy Menu comes with a few plugins that try to assist with custom paths on the menu items, but I could never get them to do exactly what I wanted. See “views integration suggestions” at http://drupal.org/documentation/modules/taxonomy_menu.
Recently I was working on a site that had a resource content type, and a resource categories vocabulary. I created a Views page with a path of resources and a Taxonomy: Term ID (with depth) argument. So, for example, I could browse to http://mysite.com/resources/my-category to show all resources tagged with “my-category.”
Now, to setup the left sidebar menu, I figured I could trick taxonomy_menu into using the right path (e.g., http://mysite.com/resources/my-category) by setting the automatic path alias to be resources/[term-name-raw] or some such thing. I force-regenerated my taxonomy menu using the Select to rebuild the menu on submit option. The menu items had the correct paths, but, to my surprise, my view did not show up; the default taxonomy listing for the term showed. So, I was halfway there. I tried several other ways of making this work, but the solution actually proved to be clean and easy. I reverted my pathauto settings back to the default for this vocabulary.
I discovered the solution in the API docs for the module. There is a hook called hook_taxonomy_menu_path that lets you define your own path settings. Once you’ve defined your path settings, they’ll show up in the “MENU PATH TYPE” dropdown when configuring the taxonomy menu (which you will find at the bottom of the vocabulary’s edit screen).
It took me some monkeying around to work out the logic for getting a clean version of the path, but I was eventually able come up with some decent, concise code that does the trick. After writing the code below in a module, I reloaded the vocabulary settings page. Then, I chose my new option from the select list. Again, I clicked the Select to rebuild the menu on submit checkbox and submitted the form. To my surprise it worked perfectly. I now had completely customized paths for my term menu items. The paths pointed to my view as desired.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/** * Implementation of hook_taxonomy_menu_path. */ function mymodule_taxonomy_menu_path() { $output = array( 'mymodule_taxonomy_path_resources' => t('Resource Categories') ); return $output; } /** * Callback for hook_taxonomy_menu_path. * * NOTICE: taxonomy_menu module weight MUST be greater than * pathauto's (which is 1 by default) for this to work * because we need the alias for processing! * * Set the module's weight to 2 using something like: * UPDATE system SET weight = 2 WHERE name = 'taxonomy_menu'; */ function mymodule_taxonomy_path_resources($vid, $tid) { if ($tid == 0) { $path = "resources/all"; } else { $default_path = drupal_get_path_alias(taxonomy_term_path(taxonomy_get_term($tid))); $clean_path = str_replace('category/resource-categories/', '', $default_path); $path = "resources/{$clean_path}"; } return $path; } |
The options here are endless, given that you can completely customize the path. It’d be cool to be able to do it per-menu, per-vocabulary, but in most cases, you’ll only have one term menu pointing to one single view.
One last note: My callback function uses the term’s path alias, which works great if you’re working with existing terms as we were doing when we used Select to rebuild the menu on submit option. When creating new terms, the issue is that if pathauto hasn’t given the term an alias yet, then the path to our menu item will be undesirable. So, you need to make sure the taxonomy_menu module’s weight is greater than that of pathauto (which has a default weight of 1). Here are some SQL commands that will achieve this (I’m not sure you need to set the weight on any more than the actual module, but it might be a good idea to set the weight on all related modules):
1 2 3 4 |
UPDATE system SET weight = 2 WHERE name = 'taxonomy_menu'; UPDATE system SET weight = "2" WHERE name = "taxonomy_menu_hierarchy"; UPDATE system SET weight = "2" WHERE name = "taxonomy_menu_path_custom"; UPDATE system SET weight = "2" WHERE name = "taxonomy_menu_vocabulary_path"; |
PHP Code to Output a List of Terms Linked to a Custom View
You can call a function like the one below in a block or in a template to render a list of HTML links for each term in a vocabulary. In my case, the resources vocabulary has an ID of 1. The view is setup to accept a Taxonomy: Term ID argument that is set to validate on Term name/synonym converted to Term ID. Also, it’s set to Transform dashes in URL to spaces in term name arguments.
Just like above, the default Automated Alias Settings for the Resource Categories vocabulary is setup as category/event-categories/[catpath-raw]. Hopefully, the [catpath-raw] (or [cat-raw] if you want) will match the term name or synonym.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/** * Generate simple links to resources with a resource term argument * * @return * HTML list of links to a view with a Term ID argument * that should match a term name or synonym */ function mymodule_resource_term_links() { $links = array(); $result = db_query('SELECT tid, name FROM term_data WHERE term_data.vid = "1"'); while ($term = db_fetch_array($result)) { $default_path = drupal_get_path_alias(taxonomy_term_path(taxonomy_get_term($term['tid']))); $clean_path = str_replace('category/resource-categories/', '', $default_path); $links[] = l($term['name'], "resources/{$clean_path}"); } return theme_item_list($links); } |