Last updated May 10, 2014. Created on March 16, 2008.
Edited by greggmarshall, jhodgdon, kkaefer, ergophobe. Log in to edit this page.

Document status:
[Done] Create base page for Views 2.x documentation
[TODO] almost everything

Views is a flexible query builder that will allow your module to expose its data so that Views can build queries with it. While Views has a pretty good idea of how Drupal Core is laid out, you as a developer, must tell Views what to do, or it can't handle your data.

But, if you give Views the proper information, Views can incorporate your module's data and help you build queries.

Views needs to know the following things:

  • Each table that contains data that Views might use.
  • Whether or not this table is a 'base' table, which means that it is presented as a 'view' type. For example, node, users and comment are all 'base' tables.
  • How this table relates to existing base tables; these relationships are 'default' or 'implicit' relationships. There are also explicit relationships which can be added via the UI.
  • What fields users can display in list/table type views.
  • What fields users can sort their views on.
  • What fields users can filter their views on.
  • What arguments users can provide their view to do filtering via the URL and create summary views.

Your module should define default views so that users can immediately do obvious things with your data without having to build their own views, and several hooks to help you modify a view at various points while it is being built.

In addition, you can also define displays, styles, row styles, default argument handlers and argument validators, which are not necessarily related to tables.

How Views works

At its very core, Views uses an object which is a generic query builder. When the $query object is instantiated, it needs to be told what the 'leftmost' table is. This is the 'base' table, or the 'view type'. When tables are added to the view it needs to know how they are linked to the base table. This helps Views do a lot of setup without the user having to know or care about the exact relationship between a particular piece of data and the core node table.

Armed with this relationship data, when fields are added to a view, either for display, or for sorting or filtering, the query object automatically determines the relationship of that field's table to the node table, and adds the appropriate joins. The core methodology of this system is quite simple.

What your module needs to do

At a minimum, if your module wants to use Views, it needs to implement one hook:

  function hook_views_data();

This function returns data that will describe how your module's tables relate to the Drupal node table, as well as what fields can be displayed and sorted, and how your tables may be filtered. This hook can return just one or many tables. This function should be placed in a file named in your module's directory. Views will automatically find it and include it when necessary.

If you want to provide default views that your users can immediately use, implement hook_views_default_views(). You can use the views exporter tool to create this hook. This hook should be placed in

External links

Advanced help

There is a lot more documentation for Views 2 in the advanced help packaged with Views. Go to admin >> advanced help >> views >> api (help/views/api).

Looking for support? Visit the forums, or join #drupal-support in IRC.


kranklin’s picture

Anyone learning how to program with views 2 will probably find this helpful:

evoltech’s picture

It took me a while to figure out with the extended help (help/views/api-tables) exactly how to reference an external database in the base table description. The documentation reads: "If this table is held in a different database from your Drupal database, specify it as a string in the exact same format as the settings.php file.". The string you specify there is the key from your settings.php file that references your external database. For example:

//in settings.php for your site
//your drupal (site) database needs to be called 'default'
$db_url['default'] = 'mysqli://user:pass@host/drupal_db';
$db_url['budget'] = 'mysqli://user:pass@host/other_db';

Then when you are describing your base table you would write something like this:

$data[$table]['table']['base'] = array(
    'field' => $primary_key,
    'title' => t($table_display_name),
    'help' => t($table_display_description),
    'database' => 'budget',
    'weight' => -10,
  ); : exploit code not people

frdesign’s picture

It took me a bit to figure this out. I have two tables and I wanted to join table_b to table_a with this join:

// Only showing the relevant part of the statement
LEFT JOIN table_b
ON table_a.field1 = table_b.field1
AND table_a.field2 = table_b.field2

Views advanced help lists the available fields but there isn't sample code. This should help others who like me need to see sample code to understand how things work.

  $data['table_b']['table']['join'] = array(
    // table_a joins to table_b through field1 and field2.
    'table_a' => array(
      'left_field' => 'field1',
      'field' => 'field1',
      // adds extra fields to the join
      'extra' => 'table_a.field2 = table_b.field2',
      // Can use AND or OR, not really needed here since it defaults to AND
      'extra type' => 'AND',
gbell12’s picture

And that goes where? In hook_views_data? And doesn't $data need to be returned then?

Also what's unclear from this is how the Views UI will change to reflect this new knowledge about how two tables are joined. I mean, using the CCK, I already have the fields from all my different content types showing up when I add fields in the Views UI. But how they're joined is certainly unclear!

benoit.borrel’s picture

But notice, that as of Views 6.x-2.11, only 'extra_type' = 'AND' works.