5

I have a page where I want to display all resources for a course grouped by taxonomy term. The courses are organic groups and the resources are materials belonging to those groups. I'm using panels to display the content and I'm overriding view_node for this. I have already created a view pane which lists all the different resource categories, and I'm now trying to list all the resources for a category.

The panel is using the following URL structure:

course/course-name/resources/resource-taxonomy-term

So for instance I have a URL

/course/test-course/resources/transport

I then want to display all resources that belong to the taxonomy term "transport". So I guess the URL argument I want to pass is %4.

I've tried for over a day now trying different methods to pass the URL argument to the view without success. I've tried using a view pane to display the results and also a view block, and explored various methods of passing the argument across without success. It works fine in the view itself, but when I put it in the panel it doesn't work. Can anyone show me how I can do it?

I'm using D7.18, ctools 7.x-1.0-rc1, panels 7.x-3.0 and views 7.x-3.7.

3

Example scenario:

There is a panel containing View Content Pane.

Panel URL: /panel_url

Example with argument: /panel_url/term_name

With BEF: /panel_url?category=123

How to set up (having existing panel and added Content Pane):

  1. Add Contextual filter to the View. E.g.: Views contextual filters taxonomy name
  2. Change settings in 'View -> Pane settings -> Argument input' to load the argument 'From panel argument' (e.g. First).

Done.


In addition, if you're using Better Exposed Filters, you could do the following improvements.

To set the current active link based on the argument (if you're using select_as_links):

/**
 * Implements hook_preprocess_[themeFunctionName]().
 */
function foo_preprocess_select_as_links(&$variables) {
  $options = isset($variables['element']['#options']) ? array_change_key_case(array_flip($variables['element']['#options']), CASE_LOWER) : array();
  $selected = end((arg()));
  if (array_key_exists($selected, $options)) {
    $variables['element']['#value'] = $options[$selected];
  }
}

To set the current active link based on the argument (if you're using select):

/**
 * Implements hook_preprocess_[themeFunctionName]().
 */
function foo_preprocess_select(&$variables) {
  switch (arg(0)) {
    case 'panel_url':
      if (@$variables['element']['#name'] == 'category') {
        $options = isset($variables['element']['#options']) ? array_change_key_case(array_flip($variables['element']['#options']), CASE_LOWER) : array();
        $selected = end((arg()));
        if (array_key_exists($selected, $options)) {
          if ($variables['element']['#value'] <> $options[$selected]) {
            $variables['element']['#value'] = $options[$selected];
          } else {
            // drupal_goto('panel_url');
          }
        }
      }
    break;
  }
}

To make the links SEO friendly, you can try something like:

/**
 * Implements hook_url_inbound_alter().
 */
function foo_url_outbound_alter(&$path, &$options, $original_path){
  if (arg(0) == 'panel_url') {
    // Convert URL like: /panel_url?category=29 into /panel_url/term_name (SEO friendly)
    $path_info = parse_url($path);
    switch (@$path_info['path']) {
      case 'panel_url/term_name':
      case 'panel_url/term_name2':
        $path = 'panel_url/all'; // Convert loopy urls into base url
    }
    if (strpos($path, '?category=') !== FALSE) { // Convert term id into human name
      list(, $tid) = explode('=', current(explode('&', $path_info['query']))); // get tid from URL
      $term_name = strtolower(taxonomy_term_load((int)$tid)->name);
      $path = '/panel_url' . '/' . $term_name; // See also: $path_info['path']
    }
  }
}
  • 1
    Thank you very much for your answer. It is really helpful to see the code and how it would be implemented. Thanks again. – Ben Oct 7 '13 at 10:54
2

I've managed to solve this problem. The solution is not exactly what I was hoping for but it works.

First of all I changed the URL argument to use the term id rather than the term name in the panel. Then in the view pane, instead of using "taxonomy term id from URL" in the "provide default argument" section of the context settings, I used "raw value from URL", and specified the path component. I also needed to set up basic validation to use the term id.

I'd still be interested to hear if there is a neater way of doing this where it would be possible to use the term name in the URL instead of the id.

0

In your view pane, create a relationship with the taxonomy term. Once you've done that create a contextual filter based on that relationship to pass the term name. Set the filter to accept raw URL argument, set the item number in the path and that does it.

0

My trouble with getting the argument to pass was due to not understanding panels/page enough. I wrongly created a node (from basic page content type) expecting that I could edit it in panels to send the argument. Adding an argument in the url path always resulted in page not found.

What I later realized was that I needed go to Structure > Pages > Add custom page and then add content pane view to effectively pass the argument. Also needed to make sure that content pane view had argument input set correctly before was able to find it from the custom page.

I found where I went wrong when reading this tutorial: http://www.metaltoad.com/blog/passing-page-arguments-view-panes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.