3

I have a view that uses the id of the currently logged in user as a contextual filter. This was set using the Drupal UI and works well. Then I wrote a custom module that adds another parameter (a specific node id) to all views on my site. All views need this second parameter (and it needs to be added programmatically). This approach works well for all views that only use the programmatically added parameter as a contextual filter. However, the view that needs 2 filter values does not work, because I think I do not handle the order of parameters in the args array correctly. How do I set up views that already use filter values, but I need to add more programmatically (I set $args[0], but I guess this might be the problem) ?

I should say that I do not want those filters to appear in the URL.

testmod.module:

function testmod_views_pre_view($view, $display_id, array &$args) {
  ...
  $args[0] = $value;
}

I thought I could just read the view's $arg array and add my special argument to it programmatically, but for the view that already uses the logged-in user as a contextual filter, when I print print_r($args) it is an empty array, although the view is working correctly (and only shows results for the current user). Are contextual filters that I set up via the UI stored in a different place than $args ?

What needs to be done to tell the view how to use the 1. and 2. filter values correctly ?

Edit: I read that hook_views_pre_view() is too early to find contextual filters in the arg array (at that point you would only see arguments in that array passed via URL). Which hook would be best to achieve what I'd like to do ?

1 Answer 1

2

I now have a better understanding and found a solution. hook_views_pre_view() is indeed too early to see arguments that are NOT passed to the view via URL. That explains why $view->args was empty in my case. In hook_views_post_build() you do see ALL arguments (URL+nonURL) passed to the view. However, the way I solved my issue is still using $args[0] = $value; in hook_views_pre_view. That means the first argument passed to all views will always be $value. For views that are using additional arguments, Drupal will add them to $args later on. In my special case I have views that might not necessarily need the first argument that I pass, so I had to add a contextual filter Global: Null (at the first position) that allows a contextual filter value to be ignored (and as a default I set 0). This way each view does have the correct number of contextual filters and the order is correct, whether the view needs to use the very first argument or not. It might not seem intuituve to pass an argument to every view, even though not all views really need it, but adding a Global: Null dummy filter is easier than excluding views in an if() statement and always having to modify the module code when a new view has to be added later on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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