---
title: "Using Hook Views Query Alter · Appnovation"
url: "https://www.appnovation.com/insights/using-hook-views-query-alter"
description: "How to use hook_views_query_alter to make HTML search facets filter Drupal Views results correctly, with example code."
---

Article

# Using Hook Views Query Alter

[![](https://cdn.sanity.io/images/ey850001/production/36eb314260fb474cacc1b3a473d7e8402d997898-68x68.png?w=68&auto=format) Appno Blogger Appnovation Coop](/people/appno-blogger.md) Sep 03, 2010  
 3 min read 

![Appnovation Blog Default Header](https://cdn.sanity.io/images/ey850001/production/9efe1c26d9584ecfb3dfef5a63e698bf4567d305-1440x600.jpg?w=1400&auto=format) 

Building a website I recently ran into an issue where I had HTML search facets interacting with Drupal views. The user would click on the facet and it would filter the view depending on the argument. I ended up implementing hook\_views\_query\_alter. To make sure the values I wanted to filter on were in the view, I added the search facets into the view as fields. This automatically joins the necessary tables so that you don’t have to. Implementing hook\_views\_query\_alter requires two parameters, view and query, both are passed by reference. Since this hook is called for every view the first thing I did was check that I was altering the right query by adding an if statement that checks the view name. After that you're free to modify the query as you wish. In my example, I looped through the search facets and added them as where statements and arguments to the query.

function search\_views\_query\_alter(&$view, &$query) { if($view->name == 'example\_view\_name'){ foreach($parsed\_url AS $key => $value){ where\[0\]\['clauses'\]\[\] = 'profile\_values\_profile\_' . $key . '.value IN ("%s")'; where\[0\]\['args'\]\[\] = $value; } } } 

One of the search facets was a taxonomy filter which the user was allowed to multi select. In order to get the view to grab the correct values, I had to add join clauses to dynamically create term\_node table aliases. This is done by adding a join clause to the table\_queue and tables array elements within the query object. I was able to just copy the existing term\_node table\_queue and tables array elements because I only wanted to create different aliases. Then I incremented the existing term\_node table count within the tables array. If you wanted to create a new table join dynamically, the same approach is used but the table\_queue and tables definitions need to be created by hand.

foreach($parsed\_url AS $key => $value) { $vid = \_search\_get\_vocabulary\_id(str\_replace('\_', ' ', $key)); $tid = \_search\_get\_term\_by\_vocabulary($vid, $value); $table\_term\_node\_join = $query->table\_queue\['term\_node'\]; $query->table\_queue\['term\_node\_' . $count\] = $table\_term\_node\_join; $query->table\_queue\['term\_node\_' . $count\]\['alias'\] = 'term\_node\_' . $count; $query->tables\['term\_node'\]\['count'\]++; $query->where\[0\]\['args'\]\[\] = $tid->tid; $query->where\[0\]\['clauses'\]\[\] .= 'term\_node\_' . $count . '.tid = %d'; $count++; } 

The query table\_queue and tables array elements looks like so:

Table Queue: 'table\_queue' => array (   'term\_node' => array (     'table' => 'term\_node',     'num' => 1,     'alias' => 'term\_node',     'join' => views\_join::\_\_set\_state(array(       'definition' => array (       'left\_field' => 'vid',       'field' => 'vid',       'table' => 'term\_node',       'left\_table' => 'node',     ),     'extra\_type' => 'AND',     'table' => 'term\_node',     'left\_table' => 'node',     'left\_field' => 'vid',     'field' => 'vid',     'type' => 'LEFT',     'adjusted' => true,     )   ) Tables: 'tables' => array (     'node' => array (       'node' => array (       'count' => 1,       'alias' => 'node',       ),     'term\_node' => array (       'count' => 1,       'alias' => 'term\_node',     )   ), );

In my book this makes views more comfortable to use because it gives me more control over them. This along with a view preprocessor allows me to style and output pretty much anything I want within a view.

Building Rich Internet Apps with Drupal & HTML5 Learn the power of combining Drupal + HTML5 + CSS3 + JS  

[![](https://cdn.sanity.io/images/ey850001/production/36eb314260fb474cacc1b3a473d7e8402d997898-68x68.png?w=68&auto=format) Appno Blogger Appnovation Coop · Appnovation](/people/appno-blogger.md) 

## Keep reading

[![What is Sovereign AI](https://cdn.sanity.io/images/ey850001/production/a5889abdd5e80376912546622e046e3fbef234b4-2496x1664.png?w=640&auto=format)](/insights/what-is-open-source-sovereign-ai.md)

 Article · 7 min AI 

### [What Is Open Source, Sovereign AI?](/insights/what-is-open-source-sovereign-ai.md)

Every company is encouraging more AI, and almost every AI bill is climbing. Sovereign AI is about two kinds of control: over your data and over your costs. Here's why open source sits at its foundation.

[Iain MacNeil](/people/iain-macneil.md) Article 

[![AI-first experience design](https://cdn.sanity.io/images/ey850001/production/8bbc2418e87924ef10f36115478a2e10d5bed95e-1584x624.jpg?w=640&auto=format)](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

 Article · 6 min AI Sep 10, 2026 

### [How to Build an AI-First Experience Without Throwing Out Everything You've Already Built](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

Users now expect a direct answer, not a list of links to click through. Here's how organizations can layer an AI-First experience onto their existing website or app, in weeks rather than years.

[Andrew Douglas](/people/andrew-douglas.md) Article 

[![What Becomes Possible When AI Can Read All the Data](https://cdn.sanity.io/images/ey850001/production/c28ab0bd26753421ee42937e13adc7a7f19b47f0-1296x510.jpg?w=640&auto=format)](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

 Article · 4 min AI Sep 09, 2026 

### [What Becomes Possible When AI Can Read All the Data](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

Most of the world's data has never been analyzed, only sampled. AI changes that. How AI-ready data platforms unlock questions no one could ask before.

[Appnovation](/people/appnovation.md) Article 

## Get the thinking,  
*before everyone else.*

One considered email a month. New essays, field notes from live engagements, and the occasional strong opinion. No noise.
