Does anyone know of any good examples or tutorials on how to use the filters/arguments sections of views. I've played with it, but failed miserably! I want to display a view that is filtered by the current node id.

Any ideas?

Comments

modul’s picture

What exactly do you mean by "filtered by the current node id"? Could you give an example?

ff1’s picture

Sorry, I should have explained a bit more.

I have 2 slightly different scenarios in mind:

Scenario 1
I have 2 CCK node types, I'll call them Parent and Child. Parent node is created without any knowledge of child nodes. Child nodes are created, including a nodereference field where the parent is selected. Then, on display of the parent node, I want all the parent node data as well as a view that lists all of the related child nodes.

Scenario 2
I have 2 CCK node types, I'll call them Parent and Child. Child nodes are created without any knowledge of the parent node. Parent node is created, including a multi-select nodereference field where all the child nodes are selected. Then, on display of the parent node, I want all the parent node data as well as a view that lists all of the related child nodes.

I hope that is an adequate description of my requirements.

Thanks for your help.
Ian

ff1’s picture

I have figured out how to achieve scenario 1:

This solution creates a block on the parent node page listing all of the related child nodes.
Create your view (admin/build/views/add):

  • Make sure you tick the box to 'Provide Block'.
  • Give the block a sensible title as you will need to use it later.
  • Add all the fields you want to display.
  • Add a filter to show only nodes of type child.
  • Add an argument for the nodereference field that refers to the parent node. I also selected 'Display all values' for the default so that I could use the view for a full page as well as a block.
  • Add the following code into the Argument Code field:
    if ($view->build_type == 'block' && arg(0) == 'node' && is_numeric(arg(1))) {
      $args[0] = arg(1);
    }
    return $args;
  • Save your view.

Configure your block (admin/build/block):

  • Locate the block within the disabled section (should have the title you used earlier).
  • Select the region where you want your block to display. I selected footer.
  • Click on save blocks.
  • Click configure next to your block and fill in any information you want. I kept all the defaults.
  • Go to the 'Page specific visibility settings' section and select 'Show if the following PHP code returns TRUE (PHP-mode, experts only).'
  • Add the following code into the Pages field:
    <?php
      // Only show if $match is true
      $match = false;
      // Which node types
      $types = array('PARENT');
      // Match current node type with array of types
      if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) != 'edit') {
        $nid = arg(1);
        $node = node_load(array('nid' => $nid));
        $type = $node->type; 
        $match |= in_array($type, $types);
      }
      return $match;
    ?>

    Replacing PARENT with your node type.

  • Save your block.

You should now have a block which appears only on node pages of your parent node type and displays a list of related nodes of your child node type.

So that's scenario 1 sorted. The block stuff will be portable to any view, but I don't yet know how to define the view for scenario 2. Any help will still be greatly appreciated.

Ian

ff1’s picture

I've found a much simpler method of achieving scenario 1 here: http://drupal.org/node/124446.

One thing to bear in mind with this method is that you are editing the theme, so you will need to copy this code accross all themes used. Alternatively, you could use the contemplate module: http://drupal.org/project/contemplate.

It still doesn't provide a solution for scenario 2, but I think I am getting closer.

Ian

ff1’s picture

I have worked out how to achieve the goals described for scenario 2 above. It is not pretty... but it works.

It requires that a view is already setup with the name 'PARENT_CHILDREN'. This view should be similar to the one described for scenario 1 above, but with the arguements.

You then need to add an additional filter to that view using code within the content template form. Here is the code that I added to contemplate:

<?php
$nid_array = array();
$items = $node->field_CHILDREN;
foreach ($items as $delta => $item) {
  $nid_array[$delta] = $items[$delta]['nid'];
}
// define this section for CSS
print '<div class="PARENT_CHILDREN">';

// get the name of the view to embed as $view1
$view1 = views_get_view('PARENT_CHILDREN'); 
// add the filter
views_view_add_filter($view1, 'node', 'nid', 'OR', $nid_array, '');
views_load_cache();
views_sanitize_view($view1);

// build the view
print views_build_view('embed', $view1, array(), false, false);
print '</div>';?>

The things that you will need to change are shown in UPPERCASE.

Unfortunately, this code produced an SQL error when I first ran it. I tracked down the source of the error and found that there was already an issue raised against it: http://drupal.org/node/150517. So if you also get an SQL error when you add this code to contemplate, check out that issue. It involves modifying the code in the views module, but it's not a complex change.

I'm sure that hard-core drupal-hackers will tell me that this is completely the wrong approach to achieving the goals of scenario 2. But in the absence of any other solutions, I'm happy to run with it... for now!

Hope that helps someone.
Let me know if you get any problems with my solution.

Ian

modul’s picture

Good you got it working, ff1, and thanks for sharing the code with the community. And don't worry too much about what "harcore Drupal hackers" may (or may not) think about it. I think the one thing to bear in mind is not to hack core Drupal scripts, because that would be a pain in case of an upgrade. But for the rest, Drupal is an open PHP architecture, in which there is always place for additional code or some nifty extension, such as what you wrote.

Ludo

scottrigby’s picture

Hi,
I have a similar question to scenario 1 -- except that I want users to only have the ability to select "children" that they have edit permissions for, to associate with a parent node.

I'm doing a very similar thing - but in my version, users with appropriate permissions to edit children nodes are able to associate the parent with it through a CCK nodereference select dropdown. But they can see and associate ANY parent node. This adds that user's child to the parent of their choice. But in my case, I want users to only add children to their own parent nodes, not others without permission.

So my question is - how do I add an argument (or whatever needs to happen?) to the CCK field so users only see the parent nodes they've authored (or have permission to edit)?

Here's a more detailed description: http://drupal.org/node/192929

Thanks in advance for any insight into this

(PS, how do I subscribe to this thread so I know when someone replies? If it's an issue, I know I can always access "My Issues". But if it's not? - thx)

Scott Rigby
http://basekamp.com
http://PlausibleArtworlds.org

scottrigby’s picture

ff1’s picture

You'll need to use views to generate the list of parents. I know you can filter views to show only nodes that are authored by the current user, but I'm not sure about filtering by 'permission to edit'.

Anyway, once you've created the view you want, edit the nodereference field and select the view instead of a node type. A view can be selected by scrolling to the bottom of the 'Data settings' section and expanding the 'Advanced - Nodes that can be referenced (View)' collapsed section.

I hope this gives you a starting point. If you get stuck, post back.

Ian

pmathur01’s picture

Hi I have a situation where a user should post one image of his 10 images to a gallery. I am then publishing that gallery on the front page. I need the access to the node because when anyone clicks it should be referenced to that view. How can I achieve this? Thanks in advance.