Controlling where blocks show - node types, taxonomy vocabulary, and specific pages

Most people expect web sites to be easy to navigate. If visitors can't find what they want quickly and easily, they will probably leave your site very quickly. Controlling where block show can make your site a lot easier to navigate. This post explains how you can customise different blocks to be shown or hidden based on:

  • Whether the visitor is looking at a page of certain node type.
  • Whether they are looking at a page of a particular taxonomy vocabulary.
  • Whether they are on a specific page.

This post builds on an easier post I wrote that looked at how to control block visibility based on node types. For this post, I'll be using my films directory as a case study. As with the previous post, I'm not going to go into how to create blocks - there are many tutorials out there that can help you do this.

Context

  • I have a node type (i.e. a type of content) - film - that allows me to catalogue films I've seen recently.
  • The node type includes some taxonomy vocabularies - film series and actors/directors - that allow me to categories films. For example, if you look at a film in the Terminator series you can click a link to Terminator and see all the other Terminator films.
  • I've created some pages aand views that allow people to browse the films I've seen. For example, people can browse by genre or look browse by letter of the alphabet.
  • I have three blocks that make it easy for people to access these browse functions  - browse films, films by genre, and most recently added films.

What I wanted to do

I want these blocks to show up when:

  • A visitor is looking at an individual film (i.e. a certain node type).
  • A visitor is looking at a particular taxonomy vocabulary (a film series or an actor/director)
  • A visitor is on one of the browsing pages (e.g. view by genre or show all films).

How I did it

I achieved this by using some PHP code in the block settings. Don't worry if you don't understand PHP, you can copy this code and modify it to suit you (it goes in site building > blocks then configure your block and paste the code into 'Page specific visibility settings' - you will need to set this to 'Show if the following PHP code returns TRUE (PHP-mode, experts only)' and make sure that you are editing in plain text mode).

Here's the code I used (don't forget you will have to change some of the variables to suit your site).

  1. <?php
  2. $match = FALSE;
  3. // show block if the node type is film
  4. $types = array('film' => 1);
  5. if (arg(0) == 'node' && is_numeric(arg(1))) {
  6. $nid = arg(1);
  7. $node = node_load(array('nid' => $nid));
  8. $type = $node->type;
  9. if (isset($types[$type])) {
  10. $match = TRUE;
  11. }
  12. }
  13. // show block for certain pages
  14. $show_on_pages = array('films','films_all','films_gloss','?q=genre','genre');
  15. foreach($show_on_pages as $show_on_page) {
  16. if (substr($_SERVER["REQUEST_URI"], 0, strlen($show_on_page)+1) == "/$show_on_page") { $match = TRUE;}
  17. }
  18. // show block for taxonomy pages
  19. $vids = array(3,4);
  20. foreach($vids as $vid) {
  21. if (arg(0) == 'taxonomy' && arg(1) == 'term') {
  22. $str_tids = arg(2);
  23. $terms = taxonomy_get_tree($vid);
  24. foreach ( $terms as $term ) {
  25. $items[] = $term->tid;
  26. }
  27. }
  28. $terms = taxonomy_terms_parse_string($str_tids);
  29. //browse each value
  30. foreach ($terms['tids'] as $k => $v) {
  31. if (in_array($v, $items)) {
  32. $match = TRUE;
  33. }
  34. }
  35. }
  36. return $match;
  37. ?>

How to modify the code

Update: I've made a tool that will generate code for your site.

Setting the node type (line 4)

Change the word film to the node type for your page. You can have more than one node type by adding new elements into the array. For example, if I wanted the block to display on node type kittens as well as films, I would edit line for to read like this
$types = array('film' =&gt; 1, 'kittens' =&gt; 1);

Setting specific pages (line 14)

List all of the pages that you want the block to display on. For example, if you wanted to display the block on pages called foo, bar, and node/7 the line would be like this
$show_on_pages = array('foo','bar','node/7');

Setting taxonomy categories (line 19)

Put the ID number of the taxonomy vocabulary into the brackets. You can find the taxonomy vocabulary by going to content management > taxonomy > list - when you hover over the list terms link the ID number will be shown in the link reference in your browser's status bar (e.g. on my site, film series has this link: http:// penguin.ox4.org/admin/content/taxonomy/3). If you needed to change the IDs 6 and 12, line 19 would look like this
$vids = array(6,12);

Trust me, it works!

See this code in action on my films database.

Next, I'm trying to work out how to create a block contains all of the links (e.g. when I'm looking at the Terminator film, it will list all of the other films in the Terminator series in a block). I'll write a new updated post when I've worked out how to do that.