Controlling visibility of block content by CCK field value

Submitted by tomo on October 30, 2012 - 8:46pm

Say you have a bunch of blocks and you want them to be displayed on certain nodes of varying content type based on some criteria like the content type and some CCK fields or taxonomy. You can't do this with the stock block visibility settings without writing custom PHP code.

But we can implement it using some existing basic Drupal building blocks: CCK and Views

1. Create a content type called Visibility Block.

You might have a field for content type where the possible values are returned from code which returns an array of the content types (using function node_get_types()).

2. Then for any fields you want to match, you'll have the same fields in this content type. For example, if one of your content types has a textfield and the possible values are 1, 2, 3, then do the same for Visibility Block.

When you create a Visibility Block, you'll have your block content in the body as normal (optionally you could use Block Reference and create blocks like usual and then link to them in the node instead, but I see no point in the extra effort and redirection), then select the conditions for the pseudo-block being visible.

3. Now create a view called Visibility Blocks Viewed. You'll create block displays, one for each content type that you have a Visibility Block set for which may only be one or two of your c-types.

Create an overridden argument each block display for the content type -field- in Visibility Block. You want to match the content type of the viewed node with the field in the Visibility Block, which are not the same type of thing. So you'll need to convert the argument in code.

You'll call menu_get_object() to get the $node because it's better than "$node = node_load(arg(1));". For the chosen c-type for that block display you will check that the implied node's c-type is what ever type you want to show in this block display because you will also check any fields that are specific to this c-type. Use PHP to supply a value since no argument will be passed in, and have the code load the current node and return the type. Then use PHP for the Validator Options and if the c-type doesn't match then you will display empty text. If you have multiple c-types which share CCK fields then you can put them into a single block display.

4. For each content type, in the chosen block display you will create a new argument for each compared against CCK field. You will pick a field from V-block and then use PHP to return a default value of the currently viewed node's field's value. You won't need to do Validation on these arguments.

5. Finally, you may want to limit the number of nodes returned, maybe just one. Now give this block a title and save it and configure its region in the normal block admin.

--

Why not the normal block visibility settings?

Because there you can't even configure by content type (anymore in D6). You can configure by path glob and by PHP code which overrides the path glob field (including in the database).

So under "Page specific visibility settings", set to "Show if the following PHP code returns TRUE (PHP-mode, experts only).", the field is blocks.pages. Essentially, PHP code works by overriding the pages list.

Why not use Block Page Visibility?

Block Page Visibility (http://drupal.org/project/bpv) enables site developers to centralize the display of blocks to a single PHP function. It is an alternative to controlling display via each block's configure form. The more "sometimes on, sometimes off blocks" that a site uses, the more useful this module becomes.

This takes over the visibility settings of all your blocks by calling:

$sql = 'UPDATE blocks SET visibility = 2, pages = CONCAT("<", "?", "php ", "return bpv_is_visible(\'", module, "-", delta, "\'); ", "?", ">") WHERE status=1 AND theme=\'%s\'';

Sometimes it's easier to configure a block by just whether you're logged in, or whether you're on the front page.

This module doesn't give you any finer grained controls. And you have to configure every block in code. You also lose all your current block visibility settings once you install this module. To use this module you have to implement your own bpv_config or bpv_configuration (I think it's a bug that it's looking for bpv_configuration but actually uses bpv_config).

© 2010-2014 Saigonist.