Views Argument Handling Code

In addition to the arguments that Views supplies natively, you can also insert your own custom argument handling code using PHP (provided you have the 'use PHP for block visibility' permission). Simply expand the Argument Handling Code fieldset and enter your code.

For example:

// Make the first argument 1 if not already set
if (!$args[0]) {
  $args[0] = 1;
}
return $args;

You can also make changes to the view directly here as well:

// Show full node view, rather than teaser, if an argument exists
if ($args[0]) {
  $view->page_type = 'node';
}
return $args;

A few notes:

  1. The code should not go between <?php and ?> delimiters; just typed in directly.
  2. The code should return an array of arguments to pass into the view.
  3. You have a number of variables available to you in this handling code: all of the arguments of the views_build_view function. For full details, please see the documentation above that function in views.module.

The following is a list of variables that are ready to use:

$type
The type of view, for example 'page' or 'block.'
$view
The current view object.
$args
an array of arguments being passed into the view (for example, in the URL http://www.example.com/view_url/1/foo, $args[0] is 1 and $args[1] is foo).
$use_pager
a boolean value indicating whether current view is using a pager.
$limit
the number of rows to retrieve; required if $use_pager is TRUE.
$page
a number which indicates what page of the view to start on; used when not using $use_pager but using $limit, to retrieve only a section of the view.

Recipe: CCK Node Reference as argument

Paul Resnick - January 9, 2007 - 17:23

Suppose you want to make a block to display on node pages (URL path node/n). The block should show all the items that have a CCK Node Reference field that link to the current node id. Here's a little recipe.

First, in the Arguments section of the view, select Node Reference:.

In the Argument Code section, enter:

$args[0] = arg(1);

arg(1) is a drupal function that grabs the second argument from the URL path, in this case the node id. The query that views will build will include a WHERE clause that require to equal $args[0].

For an example of the output, see here.

Setting Dynamic Filters

quicksketch - February 24, 2007 - 05:07

You can use this field to dynamically set filters with options that may not exist. For instance, you could combine with date module and create a filter to list x number dates after a certain day, which is generated from the URL. The real trick here is if you set dynamic filters, you MUST clear the query cache so views will regenerate it for you. Example code (minus the php tags):

<?php
// Create a timestamp for two days ago
$stamp = time() - (86000 * 2);

// Generate the date parts, using our stamp OR the arguments passed in to the view
$year = $args[0] ? $args[0] : date('Y', $stamp);
$month = $args[1] ? $args[1] : date('m', $stamp);
$day = $args[2] ? $args[2] : date('d', $stamp);

// Add a filter to include only dates later than two days ago
foreach (array('year', 'month', 'day') as $part) {
 
$view->filter[] = array(
   
'vid' => $view->vid,
   
'tablename' => '',
   
'field' => 'node_data_field_date.field_date_value_' . $part,
   
'value' => ${$part},
   
'operator' => '>=',
   
'options' => '',
   
'position' => count($view->filter),
   
'id' => 'node_data_field_date.field_date_value_' . $part,
  );
}

// IMPORTANT: Invalidate the cached query for this view, as it'll need to be regenerated on each request
$view->query = '';
?>

Nathan Haug
creative graphic design        w: quicksketch.org
& software development       e: nate@quicksketch.org

Latest Views

rhys - May 29, 2007 - 10:30

The latest views.module uses

$view->is_cacheable = 0;

instead of the
$view->query = '';

Dynamic filters within a panel with pathauto

marcvangend - February 20, 2008 - 13:50

I needed to so something similar to what quicksketch described (setting dynamic filters) and I think I found a very easy way to do it. Also, it needed to work in combination with panels 2 and pathauto. Here is my solution, hopefully my code will help others.

Situation:
I am making a simple event calendar. I want a two-column panel with a list of this month's events in the left column and the description of the selected event in the right column. There is a content type called 'event' and pathauto is configured is configured to have a path like this (simpified explanation, not the actual pathauto code): agenda/[yyyy]/[m]/[d]/[title]. Of course the event content type has a cck date field to enter the event's date.

Next I created a view which displays a list with the event's title (as link) and its date. I added 4 filters:
[0] field_datum_value_year=now
[1] field_datum_value_month=now
[2] published=true
[3] node_type=event

My panel page is set up to override the event node, so when an event node is called, the panel is displayed with the event in it's right column. The panel loads the view in the left column. The path of this panel page was set to 'agenda'. The result so far is a panel which displays this month's events on the left and, when an event in this list is clicked, displays the event node on the right.

Here comes the dynamic filter part: I want to access the calendar of other months by passing arguments to the page. The path agenda/2008/4/ should show the calendar of april 2008. As you have seen, I already had the year and month filters in place. This means that I don't have to create the filters completely with the argument handling code; I can just override the 'value' variable when an argument is available. The code looks like this (without the '<?php' of course):

<?php
if ($args[0]) {
   
$view->filter[0]['value'] = $args[0]; // set the value of filter[0]
}

if (
$args[1]) {
   
$view->filter[1]['value'] = $args[1]; // set the value of filter[1]
}

$view->is_cacheable = 0;
?>

As you can see, I use much less code than quicksketch, because I only set the values that need to be changed.

This works perfectly, but there was one problem. When I was at agenda/2008/4/ (now = 2008/2) and clicked one of the events in the list (let's call it 'workshop'), the event node was displayed in the right column, but the view on the left was reset to the default, being the current month. The reason for this is, that the path changed to the path of the event node, which has no arguments. The actual path was 'node/21' while the path alias was 'agenda/2008/4/16/workshop'. That's why I had to add some more code: to make sure that the view didn't reset to the default month when an event was opened. Now the argument handling code looks like this (again without the '<?php'):

<?php
if (!$args[0]) { // if there are no arguments, we may be looking at an event node
   
$path = explode('/', drupal_get_path_alias($_GET['q'])); // get the current path, lookup the path_alias and turn the pieces it into an array
   
if (($path['0'] == 'agenda') && is_numeric($path['1']) && is_numeric($path['2'])) { // check if $path contains a year and month after 'agenda/'
       
$view->filter[0]['value'] = $path['1']; // set the value of filter[0]
       
$view->filter[1]['value'] = $path['2']; // set the value of filter[1]
   
}
}

if (
$args[0]) {
   
$view->filter[0]['value'] = $args[0]; // set the value of filter[0]
}

if (
$args[1]) {
   
$view->filter[1]['value'] = $args[1]; // set the value of filter[1]
}

$view->is_cacheable = 0;
?>

Well, that's it! I would like to hear your opinions (positive and negative) about my solution. I'm quite pleased with it myself, but maybe I just didn't discover the disadvantages of this method yet... Thanks for reading, anyway!

Content in block 'user whose profile's page is being looked at'

jmav - March 18, 2007 - 20:52

Best solution - needed at least half a day to figure out.

Put code below in Argument Handling Code section of view module.

  if (arg(0) == 'user' && is_numeric(arg(1))) {
    return array(arg(1));
  }

Details at:
http://drupal.org/node/111639

Adding Sorting Behavior w/ Argument Handler Code via $view

KentBye - May 24, 2007 - 07:44

I was able to add sorting behavior to a view by adding a URL argument that programatically changed the view within the Views Argument Handling Code.

For example, when the second URL argument is "desc," then it sorts the nodes according to descending order when this code is entered as the argument handling code.

if ($args[1]== "desc") {
  $view->sort[0]['vid'] = 4;
  $view->sort[0]['position'] = 0;
  $view->sort[0]['field'] = 'node.nid';
  $view->sort[0]['sortorder'] = 'DESC';
  $view->sort[0]['options'] = '';
  $view->sort[0]['tablename'] = '';
  $view->sort[0]['id'] = 'node.nid'; 
}
return $args;

Be sure to change the view id (vid) to match your view (i.e. the last argument seen here "admin/build/views/edit/4")
If you export your view, you can start to see some details of the $view object array, but copying and pasting this into the argument handler only works with the strings and not arrays. For example, the same sorting array looks like this when you do a views export:

  $view->sort = array (
    array (
      'tablename' => 'node',
      'field' => 'nid',
      'sortorder' => 'DESC',
      'options' => '',
    ),

And doing a straight copy and paste of this into the Handler code section doesn't work.
That's because the actual $view object has a slightly different data schema for the information that's stored as arrays.
So if you want to alter the Fields, Arguments, Filters or Sort Criteria, then you should look into what the $view object array looks like.

How do you do that? Well, I did it with a debugger and took some screenshots to share what the Views $view object looks like, how it maps to the Views export, and how they are both related to the Views UI layout:
* Photo of Drupal Views.Module $View Object
* Mapping Views Export to Views $View Object
* Mapping Views UI to Views Export and Views $View Object

If you're interested in digging into the views.module code, then the Views Argument Handler Code get processed in the views_build_view() function in this section of the code:

  if ($view->view_args_php) {
    ob_start();
    $result = eval($view->view_args_php);
    if (is_array($result)) {
      $args = $result;
    }
    ob_end_clean();
  }

I set a break point in Komodo debugger after this line in order to verify that the code in $views->view_args_php was accurately altering the $view object.

$result = eval($view->view_args_php);

I'm going to play around with altering the $view object by using URL arguments, but I'd be interested in any code improvements, better ways or any pitfalls to doing this.

Dynamically adding arguments, filters & fields to a View

KentBye - June 3, 2007 - 00:58

Here's a views argument handling code snippet makes it possible to dynamically change the views $view object based upon arguments passed in the through the URL.

Given a URL of "example.com/soundbite/interview/argument_input" where
* "soundbite" is the views Page URL
* $args[0] triggers the Views Argument Handling Code when equal to "interview"
* And $args[1] is the input to the views argument query that is generated within the Views Argument Handling Code

if ($args[0]== "interview") {
  $view->argument[0]['vid'] = $view->vid;
  $view->argument[0]['type'] = 'content: field_interview';
  $view->argument[0]['argdefault'] = '1';
  $view->argument[0]['title'] = '';
  $view->argument[0]['options'] = '';
  $view->argument[0]['position'] = 0;
  $view->argument[0]['wildcard'] = '';
  $view->argument[0]['wildcard_substitution'] = '';
  $view->argument[0]['id'] = 'content: field_interview';
}
$args[0] = $args[1];
$args[1] = '';
$view->query ='';
return $args;

Note that $args[1] replaces $args[0], and that the $view->query is cleared out so that _views_build_query() is triggered to rebuild and modify the query.

There could be other conditionals that can be used to dynamically change the fields, arguments and filters of the view based upon the arguments.

A brute force approach of cloning and creating multiple views is probably sufficient in most cases, but there may be a case where you want more sophisticated control. See the comment above for more details on how to format the data in the views $view object since it'll be different from what you see from a views export.

Turn off caching

caign - June 12, 2007 - 01:46

... $view->query is cleared out so that _views_build_query() is triggered to rebuild and modify the query.

This did not work for me, but I found I could turn off caching for the view which did the trick:

$view->is_cacheable = 0;

Sort behavior with get parameters

Sean B Fuller - February 19, 2008 - 04:45

Great tip! I'm trying to add some custom sorts to teaser lists on a 5.x site, but I was having problems getting this to work with pathauto. When I had a built-out alias for a taxonomy/term/ page in the form of [vocab-raw]/[term-name-raw] and tried adding an argument it would result in a 404. This is because the argument was essentially telling drupal to look for a different page.

My current solution is to check for two get parameters (sort and order) instead of the args. This keeps the alias working, but also let's me sort. Additionally, it keeps me from breaking my feed arguments and aliases. My code looks like this:

Views:

if ($_GET['sort']== "title") {
  $view->sort[0]['vid'] = 10;
  $view->sort[0]['position'] = 0;
  $view->sort[0]['field'] = 'node.title';
  $view->sort[0]['sortorder'] = $_GET['order'];
  $view->sort[0]['options'] = '';
  $view->sort[0]['tablename'] = '';
  $view->sort[0]['id'] = 'node.title';
}
else if ($_GET['sort']== "date") {
  $view->sort[0]['vid'] = 10;
  $view->sort[0]['position'] = 0;
  $view->sort[0]['field'] = 'node.created';
  $view->sort[0]['sortorder'] = $_GET['order'];
  $view->sort[0]['options'] = '';
  $view->sort[0]['tablename'] = '';
  $view->sort[0]['id'] = 'node.created';
}
return $args;

And I have code in my theme to add the links, which looks like this:

  // Set up basic variables
  $sort = trim($_GET['sort']) ? $_GET['sort'] : 'date';
  $order = ($_GET['order'] == 'asc') ? 'asc' : 'desc';
  $reorder = ($order == 'asc') ? 'desc' : 'asc';
  $output = '<div>';
 
  // sort by title
  $title_link = ($sort == 'title') ? t('TITLE') .' '. theme_tablesort_indicator($order) : t('TITLE');
  $output .= l($title_link, $_GET['q'], array(), '&sort=title&order='.$reorder, NULL, FALSE, TRUE);
 
  // sort by date
  $date_link = ($sort == 'date') ? t('DATE') .' '. theme_tablesort_indicator($order) : t('DATE');
  $output .= ' | '. l($date_link, $_GET['q'], array(), '&sort=date&order='.$reorder, NULL, FALSE, TRUE);

  // wrap it up and return
  $output .= '</div>';
  return $output;

Seems to work so far. I'll report back if I run into anything.

--------------------
Sean B. Fuller
www.seanbfuller.com

My argument handling code

wedge - June 7, 2007 - 08:48

I wanted to add a filter to select songs with a certain metadata tag. This is my code.

<?php
if (isset($args[0])) {
 
views_view_add_filter($view, 'audio_metadata_genre', 'clean', '=', $args[0], '');
 
views_sanitize_view($view);
}
return
$args;
?>

For this to work you have to make sure that views knows about the table you are selecting from. At the moment I'm not really sure how to do this. The audio-module did this for me automatically in this case.

Using custom node paths as arguments

drowlflood - June 15, 2007 - 08:53

I created a custom node type with CCK in Drupal 5.1 and turned on the Pathauto module to generate SEO-friendly URLs based on its title, like "http://www.example.com/title_of_node".

I also wanted to create a view of the node using just a subset of its fields, while still keeping the custom path name, like "http://www.example.com/teaser_view/title_of_node".

The views module doesn't allow you to add arguments based on a node's URL path setting, just on its title which can include spaces that make for some ugly URLs.

To get around this limitation, I added an argument based on the Node: ID to my view and pasted the following php into the Argument Handling Code field to lookup the ID based on the path alias:

$result = db_query("SELECT src FROM {url_alias} WHERE dst LIKE '%s'", $args[0]);
$nodeid= array();
while ($nodepath = db_fetch_array($result)) {
  $nodeid[] = substr(strrchr($nodepath['src'], "/"), 1);
  return $nodeid;
}

This works great, except for the fact that if I put a random title in after the view URL, I'm getting a SQL error instead the usual Permission Denied screen. Any idea how to make this fail gracefully?

Edit

NikLP - July 17, 2007 - 17:34

I've seen this code and it took me a while to get it working (ages, in fact) because there was a bit missing - there should be two ampersands each side of the %s, inside the single quotes. Maybe the code filter pulled them out, which is why they're not there. I will post my code here and see :)

As for degradation, I was told about maybe cheekily using drupal_not_found(), but it didn't seem to work. Also, I have wrapped my while() in a test, but without a meaningful else {} at the bottom, it's useless.

$result = db_query("SELECT src FROM {url_alias} WHERE dst LIKE '%%%s%%'", $args[0]);

if (isset($result)) {
  $nodeid= array();
  while ($nodepath = db_fetch_array($result)) {
    $nodeid[] = substr(strrchr($nodepath['src'], "/"), 1);
    return $nodeid;
  }
}

I hope this helps someone, cos it took me ages to sort out.

Default arguments from panels

Grugnog2 - July 29, 2007 - 07:18

The current (1.0) version of panels passes the '%1' (or whatever) into the view directly as a string, if that argument is not present.

You can easily correct this using some code like:

<?php
if ($args[0] == '%1') {
 
$args[0] = 'all';
}
return
$args;
?>

Defining Different View Type Depending on Vocabulary ID

ivan.g - October 27, 2007 - 10:43

If you want to differ view type depending on vocabulary.
Example:
You have one view which responds to "taxonomy/term/$arg" URL.
You have selected "Argument" Field as "Taxonomy: Term ID" and set it to "Display all values"
You have specified the view to be "Bonus Grid" view for Page and/or Block and this view works perfectly to show your products (may be other content type) depending on term from taxonomy tree. Now, as you may expand your taxonomy to use different vocabularies and assign terms from them to different content types (page, for example), you will face the problem that clicking a term may display your "Pages" in "Bonus Grid" view - which is not what you want.

Here's a solution how to use "Argument Handling Code" to separate view type depending on vocabulary:
In the example I am using vocabulary ID (vid) as 2:

$Product = FALSE;
$args[0] = arg(2);
$tid = $args[0];

$query = db_query("SELECT d.vid from {term_data} d WHERE d.tid  = '%d'", $tid);

$vocab = db_fetch_array($query);

$nodeterm = array();
foreach ($vocab as $term) {
  $nodeterm[$i] = $term;
}
if(in_array(2, $nodeterm)) // This is where you specify your required vocabulary ID - which is 2 in my example and/or specify multiple id's if you like
{
  $view->page_type = 'bonus_grid'; // for vid = 2 we are showing Bonus Grid view
} else {$view->page_type = 'teaser';} // for any other vocabulary we show Teaser view.
return $args;

This code works for me perfectly and I hope will be in use to some of you, guys.

View for taxonomy/term for specific vocabulary category

Blackguard - February 26, 2008 - 19:55

Thanks for the code ivan.g!

I used it to solve a similar problem. If you want a specific view type only for terms from a specific vocabulary, you can use this argument handling code.

Make a view with an url taxonomy/term

Give it the argument Taxonomy term ID. Provide page view and use pager should be 'on'.

Let your view provide the default type of view, usually Teaser list.

Argument handling code:

$tid = $args[0];

$vid = db_result(db_query("SELECT vid FROM {term_data} WHERE tid = '%d'", $tid));

// replace with your own $vid values
if ($vid == 12)
{
$view->page_type = 'panels_threecol'; // replace with your desired view type
}

Explanation:
$tid = $args[0]; this grabs the tid from the url.

The next line querries the database to find out what is the term's vocabulary id.

if ($vid is equal to the vocabulary id for the following view) - in my example I want to use the panels three column teaser view for terms from two vocabularies. You can add as many vids as you want by adding the following code :
|| $vid == SOME_VID

Example

if ($vid == 12 || $vid == 9 || $vid == 1)
{
$view->page_type = 'panels_threecol'; // replace with your desired view type
}

If you are not sure what to write for the view type here :
$view->page_type = 'panels_threecol';

You can get the view type name from the export tab in your view.

Named Taxonomy term via arg

miro_dietiker - January 26, 2008 - 23:27

Using taxonomy fields in certain views is quite common. But having their IDs only in the URL is ugly.

Taxonomy terms could be filtered by Name from arg or via ID.
But if i have a specific vocabulary to be used only, i did not found a way to limit terms to. And still there where things unclear: What with special chars, ...

I decided for my ugly hack: A View with Filter by Taxonomy ID

And pass some Argument Code to lookup from $args[0] Taxonomy name to Taxonomy ID.
In this hack i use description field for URL naming ;-) ... at least for the moment!

if(isset($args[0])) {
  $query = db_query("SELECT d.tid tid from {term_data} d WHERE d.description  = '%s' AND d.vid=1", $args[0]);
  // Replace vid=1 with your Vocabulary ID!

  if(db_num_rows($query)) {
    $term = db_fetch_array($query);
    $args[0] = $term['tid'];
    #watchdog('content', 'TOPIC FROM '.arg(1).' TO '.$args[0]);
  }
}
return $args;

Example:
View URL: /yourview/the-term-name
Taxonomy Term: Name: The Term Name, Description: the-term-name
Leading to correct identification :-)

----
EDIT: For those who like it more pro style
Add Table:

CREATE TABLE `term_data_url` (
  `tid` int(10) unsigned NOT NULL,
  `url` varchar(255) NOT NULL,
  PRIMARY KEY  (`tid`),
  KEY `url` (`url`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Add the url names you like to the table to map to terms (tid from {term_data}) and use handling code:

#args[0] is arg(1)
if(isset($args[0])) {
  $query = db_query(
    "SELECT td.tid tid"
    ."\n FROM {term_data_url} tdu"
    ."\n INNER JOIN {term_data} td"
    ."\n  ON td.tid=tdu.tid"
    ."\n WHERE tdu.url = '%s'"
    ."\n AND td.vid=1" // replace it with your own vocabulary id!
    , $args[0]);

  if(db_num_rows($query)) {
    $term = db_fetch_array($query);
    $args[0] = $term['tid'];
    #watchdog('content', 'TOPIC FROM '.arg(1).' TO '.$args[0]);
  }
}
return $args;

Enjoy!

Named Taxonomy term via arg extended

cyp25 - May 13, 2008 - 13:34

Hi,

I used the code below to prevent the need to provide a description field containing the path.
The code bellow goes to Argument Handling Code

<?php
//gets the aliased path
$pathAliasedArray = explode('/', drupal_get_path_alias($_GET['q']));

//I need the third element (bar) in my case (ex : domain.com/foo/bar) only if there is a second one "foo"
if(isset($pathAliasedArray[1]) && $pathAliasedArray[1] == 'foo' ) {
  
//get real url from alias
 
$query = db_query("SELECT d.src src from {url_alias} d WHERE d.dst  = '%s'", $pathAliasedArray[0]."/".$pathAliasedArray[1]);

  if(
db_num_rows($query)) {
   
$term = db_fetch_array($query);
   
$pathReal = explode('/', $term['src']);

   
//I need the third element wich is the term id (tid)
   
if(isset($pathReal[2])){
   
$args[0] = $pathReal[2]; //taxonomy term id
   
}
  }

}
return
$args;
?>

Ciprian M.

Named taxonomy term via arg not working with Pathauto

lupus78 - May 27, 2008 - 17:05

I have the above solution and it dosen't works for me. My code is the following for "Taxonomy: Term ID" argument:

if ( isset($args[0]) )  {
$sql = "SELECT src FROM {url_alias} WHERE dst = 'video/". $args[0]."'";
$result = db_query($sql);

if (isset($result)) {
  $termid= array();
  while ($termpath = db_fetch_array($result)) {
    $termid[] = substr(strrchr($termpath['src'], "/"), 1);
  }
  $args[0] = $termid[0];
}
}
return $args;

I have the names of the terms set up with Pathauto and it is like 'video/speedflying'. If i request the video/speedflying page i get the default taxonomy term listing interface, not my view. Am I missing something? How can I disable the default for taxonomy terms?

Use Taxonomy redirect

polyfaced - June 5, 2008 - 00:39

I believe you need another module for this. I believe Taxonomy redirect is what you want, you need to specify your vocabulary to use a view instead of the default taxonomy page. so that when you go to example.com/video/speedflying it uses your custom view, not drupals default.

Taxonomy redirect: http://drupal.org/project/taxonomy_redirect

Modify filter/fields/sort via hook rather than argument handling

raspberryman - January 28, 2008 - 00:21

A more sustainable solution may be to keep argument handling code reserved for arguments, and not messing with filters, fields, and sorts.

The alternative is to use hook_views_pre_query(&$view) to modify the $view object.

If you need arguments for hook_views_pre_query(), then add them to your view object using the argument handling code:

<?php
  $view
->view_args_php = '
    $view->args = $args;
    return $args;
    '
;
?>

In addition to being conceptually cleaner and keeping argument handling domain-specific, this method reduces potential frustrations with views caching.

How to use Argument Code to create a Related Links block

davidwhthomas - January 31, 2008 - 02:24

Here's some sample code to create a 'related links' block

Views Argument Code

View: Provides Block
Type: List
Field: Node Title - link
Argument: Taxonomy: Term ID - Display All Values
Argument Code:

//return args key 0 as + separated string of tids
if(arg(0) == 'node' && is_numeric(arg(1))){
  $nid = arg(1); //node id
  $tids = db_fetch_array(db_query("SELECT tid FROM {term_node} WHERE nid = %d", $nid)); //simplest query for node tids
  if($tids){
    return array(implode('+', $tids));
  }
}

Block Visibility PHP Code:

<?php
//show block on node view pages but not on edit page
$show = false;
if (
arg(0) == 'node' && ctype_digit(arg(1)) && arg(2) !== 'edit') {
   
$show = true;
}
return
$show
?>

P.S About arg()

arg() is a function that returns parts of the non-url-aliased Drupal path (the true path)
e.g: node/123/edit
arg(0) = 'node'
arg(1) = '123'
arg(2) = 'edit'
more information is here:
http://api.drupal.org/api/function/arg/5

P.S About Views Arguments

Views arguments ($args) are different from arg().
$args = the array of returned values from the argument handling code
arg() is a function to get parts of the non-aliased url path
AFAIK:
In terms of Views arguments, the argument handling code should return an array.
The array keys (0,1,2 etc...) correspond to each view argument, in order
The array key's value corresponds to the value to pass to that argument for the view
e.g:
$arg[0] = '{term ids}'
$arg[1] = '{second view argument parameters}'
etc...

Appendix: Exported Related Headlines View

  $view = new stdClass();
  $view->name = '1_related_headlines';
  $view->description = 'Related headlines block';
  $view->access = array (
);
  $view->view_args_php = 'if(arg(0) == \'node\' && is_numeric(arg(1))){
  $nid = arg(1); //node id
  $tids = db_fetch_array(db_query("SELECT tid FROM {term_node} WHERE nid = %d", $nid)); //simplest query for node tids
  if($tids){
    return array(implode(\'+\', $tids));
  }
}';
  $view->page = FALSE;
  $view->page_title = '';
  $view->page_header = '';
  $view->page_header_format = '1';
  $view->page_footer = '';
  $view->page_footer_format = '1';
  $view->page_empty = '';
  $view->page_empty_format = '1';
  $view->page_type = 'node';
  $view->url = '';
  $view->use_pager = TRUE;
  $view->nodes_per_page = '10';
  $view->block = TRUE;
  $view->block_title = 'Related Headlines';
  $view->block_header = '';
  $view->block_header_format = '1';
  $view->block_footer = '';
  $view->block_footer_format = '1';
  $view->block_empty = 'There are currently no related links.';
  $view->block_empty_format = '1';
  $view->block_type = 'list';
  $view->nodes_per_block = '10';
  $view->block_more = FALSE;
  $view->block_use_page_header = FALSE;
  $view->block_use_page_footer = FALSE;
  $view->block_use_page_empty = FALSE;
  $view->sort = array (
    array (
      'tablename' => 'node',
      'field' => 'changed',
      'sortorder' => 'DESC',
      'options' => 'normal',
    ),
  );
  $view->argument = array (
    array (
      'type' => 'taxid',
      'argdefault' => '2',
      'title' => '',
      'options' => '0',
      'wildcard' => '',
      'wildcard_substitution' => '',
    ),
  );
  $view->field = array (
    array (
      'tablename' => 'node',
      'field' => 'title',
      'label' => '',
      'handler' => 'views_handler_field_nodelink_with_mark',
      'options' => 'link',
    ),
  );
  $view->filter = array (
    array (
      'tablename' => 'node',
      'field' => 'status',
      'operator' => '=',
      'options' => '',
      'value' => '1',
    ),
    array (
      'tablename' => 'node',
      'field' => 'type',
      'operator' => 'OR',
      'options' => '',
      'value' => array (
  0 => 'story',
),
    ),
  );
  $view->exposed_filter = array (
  );
  $view->requires = array(node);
  $views[$view->name] = $view;

Hope that helps :-)

Letting your user change number of rows returned $limit

panis - March 27, 2008 - 23:53

Also available are the exposed filters in $filters[]. You can override the user generated ones.. You can use a combination of this and the $limit to dynamically change the number of rows to retrieve.

  1. Create a dummy content type in CCK and add 1 field called 'Number of Results" or something similar to it. Make this is a numeric select field. Give it a select list of the set results you need. e.g. 10,25,50,100
  2. In your view - select this field as a filter and expose it. Select all the available values in the list box
  3. In the exposed filter mark this as optional (this will add in a '' field and also allow you to make views ignore this filter)
  4. Enable Lock operator in the exposed filter
  5. Enable Single Select in the exposed filter.
  6. Edit the Argument PHP code and insert the following code

Replace N with the number of the filter "Number of Results". for example - if this is the 3rd exposed filter then N=2.

<?php
if( !$_GET['filterN'] ) { /* replace "N" with the filter location of the exposed filter "Number of Results". */
  /* set to default of 10 or whatever you have - this will load the filter with the default value..
   * make sure that this value exists in the list of valid values for the CCK field you created above.
   */
 
$_GET['filterN'] = $limit;
}
else if (
is_numeric($_GET['filterN'])) {
 
$limit = $_GET['filterN'];
}
else {
 
$limit = 1000; /* the maximum number of values you may wish to return for 'All' */
}
unset(
$filters[N]); /* unset the filter so it does not get applied to the query. */
?>

Node reference.module views arguments

jpsalter - June 9, 2008 - 04:17

I needed to build a view for a node reference field that filtered content by a term of the node being edited. You cannot use arg(1) since the view is being called via the autocomplete function. You can figure out the nid from the variable $_SERVER['HTTP_REFERER']. Here is the code I used.

<?php
  $matches
= array();
 
 
// get node ID from node being edited
 
preg_match('`node/(.*)/edit`',$_SERVER['HTTP_REFERER'],$matches);
 
$nid = $matches[1];
 
 
// get term(s) from vocabulary #5 of this node
 
$term = taxonomy_node_get_terms_by_vocabulary($nid, 5);
 
 
// set tid as argument for node reference view
 
$view_args[0] = key($term);

  return
$view_args[0];
?>

Dynamic filter based on uid

sw9 - June 20, 2008 - 17:28

For anyone trying to dynamically add a filter to parse nodes based on uid/author, hopefully I can save you some time. I had a cck type that had a node reference field, and I wanted the following to happen:

- If the user was of a particular role, show ALL nodes in the node reference field
- If the user was not of a particular role, ONLY show nodes that they authored

So in the node reference field settings, I wanted to use a view.

I tried to get a filter working for this via views arguments to dynamically add it with 0 luck. But I finally stumbled on this page which will do exactly what I've said: http://drupal.org/node/162679

Hope that helps someone. Could'a saved me 3 hours!

Subscribing, greetings, Marti

Summit - June 23, 2008 - 07:53

Subscribing,
greetings,
Martijn

 
 

Drupal is a registered trademark of Dries Buytaert.