Modifying Views Filters programmatically

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
timting's picture

I've been trying to create a view for blog posts which given the url, say, "blog/after/2010/02/02", will take those arguments and give me the 10 entries in my blog after 2010/02/02. I thought it would be relatively simple, but I haven't been able to find enough information on the web in order to do this. I'm not sure if I've taken the right approach. I've used http://groups.drupal.org/node/82219 as a template to use the hook_views_pre_view() function to access my view's filters (I've created a created filter on the blog entry post date) and modify it with the arguments on the URL. Unfortunately, it doesn't seem to do anything to the end result. My code is something like this:

function timting_views_pre_view(&$view, &$display_id, &$args) {
if($view->name == 'blog') {
$filters = $view->display_handler->get_option('filters');

    $filters['created']['value']['value'] = $args[0] . "/" . $args[1] . "/" . $args[2];
    $view->display_handler->override_option('filters', $filters);
}

}

Unfortunately, I'm pretty new to this and I'm not exactly sure if there's a function I need to call to update the filters afterwards. Another possible problem is that I'm not using the default display; I'm using a page display - do I need to target this in the function?

Or am I going about this in a totally wrong way? Any help would be appreciated - if you need more details on the problem, please do ask. Thanks so much!

Comments

Arguments vs Filters

omerida's picture

Keep in mind thatin views Filters and Arguments are two different things. If you are using arguments, which look like parts of the url path, then you can call your view using views_embed_view (http://groups.drupal.org/node/17397).

$output = views_embed_vide('blog', 'default', 2010, 2, 2);

or
$output = views_embed_vide('blog', 'page_1', 2009, 2, 2);

and so on.

I do realize that Filters and

timting's picture

I do realize that Filters and Arguments are two different things; I was hoping that I could use the hook_views_pre_view to hook into the views flow, take the Arguments, and use them to modify a Filter, which would in turn modify the query.

Is that possible?

i don't see why you need to

omerida's picture

i don't see why you need to do that, arguments modify the query as well, so why not use them to affect the output?

I'm trying to do as much in

timting's picture

I'm trying to do as much in the Views GUI as possible and only do stuff with hooks when I have to, and arguments don't have the capability (at least I didn't see) to say, "get the 10 entries after this date". All I could get the arguments to do was "get entries on this date".

But, forget that. If I were to take your approach, would I take the arguments and then modify the query directly in the hook? Which hook would you recommend, and could point me towards what in the view I would need to modify?

Thanks!

Views API has examples

omerida's picture

See how to call a view from php http://groups.drupal.org/node/10129 One way to do this would be to create a custom block that uses the Views API and displays the rendered output.

That page

lsiden's picture

That page (http://groups.drupal.org/node/10129) is a great resource! Thank you!

I was trying to do the same thing. I want to search for a user that contains part of a full name (from a linked content_profile node). So in SQL-ish, the query should look like "UPPER(node_data_field_fullname.field_fullname_value) LIKE UPPER('%joe%')" assuming the user is looking for someone with "joe" in his name.

I wanted to use Views arguments, but the Views UI doesn't give me any way to specify an operator for an argument. Only the Filters part of the UI allowed me to specify an argument like "contains".

So what I got to work is:
$view->exposed_input['field_fullname_value'] = $string;

This is alright, but I would have really preferred to tell the Views UI to set the "contains" filter value from an argument. Then, I could do something even more straightforward, as in this example that I already use:

  $view = views_get_view('claims_listing');
  $view->set_display('default');
  $view->set_arguments(array($id));
  $view->is_cacheable = FALSE;
  $view->render();
  return $view->result;

Why can't I link a filter value to an argument so that I can apply an operator to it?

Simple way to modify view filter is using view hooks

purabdk's picture

Using following code you can modify the view filter dafault values:

<

pre>

<?php
/<strong>
*
hook_views_pre_view
* @param type $view
* @param type $display_id
* @param type $args
*/
function
MODULE_NAME_views_pre_view(&$view, &$display_id, &$args) {
  if (
$view->name == 'VIEW_NAME') {
   
$filters = $view->display_handler->get_option('filters');  
   
$view->display_handler->override_option('filters', $filters);
  }
}



/</
strong>
*
hook__views_pre_build
* @param type $view
* @return type
*/
function
MODULE_NAME_views_pre_build($view) {
  if (
$view->name=='VIEW_NAME') {  
   
$view->display['page']->handler->handlers['filter']['filter_field']->value['value'] = 8;
    return
$view;
  }   
}
?>

Software Development

Did not work

juampynr's picture

This solution did not work. I got it working with http://drupal.stackexchange.com/a/49480/4942

Senior Developer at Lullabot
https://www.lullabot.com/who-we-are/juampy-nr

It works

rodpal's picture

It works perfectly using pre_build hook with an existing filter. This is my code.

/* hook__views_pre_build
* @param type $view
* @return type
*/
function filtra_reels_views_pre_build($view) {
if ($view->name=='articulos_listado_filtro') {

$view->display['panel_pane_6']->handler->handlers['filter']['nid']->value['value'] = '101619';
return $view;

}
}