Contextual View Blocks

Last modified: June 1, 2007 - 20:06

The basic technique here is to decorate an existing page (a node page, or another view) with a view block, and then to take the parameters for the view block from the path, By placing a snip of php code like the following in the "Argument Handling Code" section of the view configuration field for the view:

In 4.7:

<?php
if ($view['type']=='block' && arg(0) == 'node' && is_numeric(arg(1)){
 
$arg[0] = arg(1);
}
?>

In 5.x:

<?php
if ($view->build_type == 'block' && arg(0) == 'node' && is_numeric(arg(1))) {
 
$args[0] = arg(1);
}
return
$args;
?>

NOTE: The code should not go between <?php and ?> delimiters; just typed in directly.

This code is called whenever the view is accessed. It says "If the view is a block, and the path is "node/n", where n is an integer, then set the view's first argument to the integer. We know that paths that look like /node/n point to a node.

"But what if I'm using pathauto.module to set up custom paths for my nodes?", you may ask. Well, path aliases only change the outward-facing path. Internally, modules will still see the original, canonical path (ALWAYS!). This is very useful.

Now we should set up our view so that it takes that argument from the path and actually does something useful with it. Examples:

  • Show all the nodes authored by the current user whenever someone visits "/user/n"
  • If you use CCK, show all the nodes referenced by the current node.

Some more advanced ideas:

  • Check the path in the "Block Visibility" field of the block config page for the view block instead of in the view argument section, like:
    <?php
    if (arg(0)=='node' && is_numeric(arg(1)) { return TRUE; }
    ?>
  • Actually load the node with:$node=node_load(arg(1)); and then use fields on the node (such as $node->type and $node->uid (author)) as parameters. You can also use this technique without views, printing out fields from the current node in a custom block. Also, node_load caches the node object, so this is actually not a significant performance hit (the node is already being loaded for display).

Here's my recipe

dman - June 22, 2007 - 12:21

I needed to upgrade the behaviour of earlier solutions like 'sidecontent' or my home-rolled 'relatedblock' to just

Add a textarea where we can put content to show up in a block beside a node

I want a column called 'adcolumn' which is hand-filled to show stuff relating to pages. A 1-1 relationship.

  1. Create the Field

    Enable Views and CCK and Text field

  2. admin/content/types/page . Add Field. Text. Called adcolumn (10 rows). Text processing: Filtered text . (we'll come back later after testing)
  3. Create/Edit a node page. Cool, the new field appears. Put something in it and save to look at.
  4. Create the Block

    Add a view. admin/build/views/add . Called adcolumn also if you like, it's not important and they don't conflict.

  5. Description: "Block that shows up beside the node". No page view. No Menu. Yes, Provide Block.
  6. View Type: Table or List view (Neither are optimal, I'm looking into that)
    Title: optional
    Nodes per Block: 1 I guess. Doesn't make a difference.
    No more link, no header or footer or empty text (for me).
  7. Add Field: Text: adcolumn. Press [Add Field].
    No sorting etc options need to be changed. (Label:blank, Handler:Group, option:default, Sortable:no, Default Sort:none)
  8. Here's the fun:
    Add Argument: Node: ID
    Default: Empty Text, Title: blank, Option: equal, Wildcard:blank, Wildcard Sub: blank
  9. As in the instructions above, add code
    Argument Handling Code
      if (arg(0) == 'node' && is_numeric(arg(1))) {
        return array(arg(1));
      }
    NO PHP TAGS
  10. ... and save.
    Almost there...
  11. Enable, theme, layout

    Visit admin/build/block and shift the new block into a sidebar or something.
    Have a look at the page you added side content to before.
    It should start showing up!

  12. Depending on your theme, you may also be seeing it repeated in your page as well. That's the normal behavior for CCK fields.
    Turn it off by visiting [Administer - Content Management - Content Types - Page] and clicking the "Display Fields" tab.
  13. Set all values for 'adcolumn' to Hidden and submit.
  14. Go back to your page. phew Cool!

It's all cool once you know what you are doing, but I got sidetracked trying to grok argument handling.
The content shows up unneccesarily framed in either a LI or a table cell. I guess this can be fixed with views theming, but I'm just going to normalize it with CSS tody.

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

Context sensitive embeded views

jfall - February 16, 2008 - 06:33

Here's an article that uses these ideas to embed a context sensitive view on a page that pulls in other content created by the owner of that page, based on a Node Reference.
See : http://drupal.org/node/221919

Context in Views 2.x

gurubert - July 16, 2008 - 21:34

Adding conext sensitivity in Views 2.x has become much easier.

When adding an argument to the view select Provide default argument for the Action to take if argument is not present.
Then select a Default argument type which could be the Node ID from URL for the example above.

That's it.

To display a view within a node use the CCK field type view reference which will show the view. No need for any template code editing.

CCK Blocks

nedwardss - January 21, 2009 - 22:37

After searching through and doing the above (which works), I discovered CCK Blocks http://drupal.org/project/cck_blocks which can do this quite elegantly.

Thanks

lameei - February 4, 2009 - 15:15

This is what i used.........

I am using the code above in

hampshire - May 21, 2009 - 16:02

I am using the code above in drupal 5 to call the authors node profile info and desplay it in a block. This works great as long as I let the views module display the info in a list. If I create a template file however I run into problems. I have a file block-views-VIEW_NAME.tpl.php and all my html from the template displays in the block but none of my php does.

For example

<?php print $node->field_authorprofile_name[0]['view'] ?>

would not call the authors name even though the authors named displayed just fine in the standard list view that views uses by default.

Can anyone recomend a way to customize my output using templates. I already have a node-CONTENT_TYPE.tpl.php file with a teaser and full version of the authors info so I do not believe I can use this template for my block.

Thank you.

 
 

Drupal is a registered trademark of Dries Buytaert.