Views 1 module developer API

Last modified: March 8, 2009 - 09:28

Document status:
[Done] Tables parts 1-5
[Done -- badly] Arguments
[Done] Default Views
[Done -- needs polish] Style plugins
[Done] Other hooks
[TODO] $query object
[TODO] $view object
[TODO] Functions
[TODO] node_example
[TODO] amazontools
[TODO] 'multiple' fields
[TODO] views_build_view
[TODO] troubleshooting

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.
  • How this table relates to the Drupal node table, either directly or indirectly.
  • 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.

In addition, you can provide style plugins to help control how views that use your module's data are presented, 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.

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 (for Views this is always node), and when tables are added to the view it needs to know how they are linked to the node 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:

<?php
  $query
= new _views_query();
 
$query->add_field($field, $table, $alias);
 
$query->add_orderby($field, $table);
 
$query->add_where($clause);
?>

Obviously, more layers end up adding more complexity; some relationships aren't as simple as others and are more difficult to describe, especially when they are abstract, such as those found in the Content Construction Kit (or flexinode).

What your module needs to do

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

<?php
 
function hook_views_tables();
?>

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.

Additionally, if you want to provide URL arguments, you'll want to implement hook_views_arguments() to return a similar but smaller chunk of data, and if you want to provide default views that your users can immediately use, implement hook_views_default_views().

Basic code to get the view's data

heronog - June 30, 2007 - 16:26

this code is a function I wrote while learning how to make views.

What it does is that it gets the formated fields for every node in the view and puts it in a nested array.

function theme_something_display(&$view, &$items, $type) {

    $fields = _views_get_fields();
  
    foreach ($items as $n=>$node) {
        foreach ($view->field as $id => $field) {
            //This where the real work is.
            $vars[$n][$field['field']] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);

        }
    }

    //Let's see what we came up with. You should really get this line out of your code once you see what it does.
    print_r($vars);

    return "WHATEVER_YOU_WANT_TO_DO_WITH_THE_VARS";
}

I am posting it here because it took me a couple hours of reading to figure this out, and since there is a lot of gaps in the Views api documentation, I tought it could be useful to those trying to create new view types.

This is a sample output from my dev installation. The view has two fields, Title and an image attachment as a thumbnail.

Array
(
    [0] => Array
        (
            [title] => Item1
            [iid] => <img src="http://devsite/files/images/Picture1.thumbnail.png" alt="Picture1.png" title="Picture1.png"  class="image image-thumbnail " width="100" height="83" />
        )

    [1] => Array
        (
            [title] => Item2
            [iid] => <img src="http://devsite/files/images/pic2.thumbnail.jpg" alt="pic2.jpg" title="pic2.jpg"  class="image image-thumbnail " width="100" height="14" />
        )

)

Hope this helps someone.

Sorting numeric data in character fields

drewish - August 29, 2007 - 20:49

I did a little write up on how to get views to properly sort numeric data that's stored in character strings: http://drewish.com/node/93

Hopefully it'll save someone else some trouble.

Field from table join not found in Views 1

manfromochie - March 18, 2009 - 04:24

Help spend 1 week trying to ge this to work.

I am trying to create a view programatically using php in a page content type. I followed the example for building a view with data from your own sql query. i cannot find an example of this. I am not creating a module. However from looking at the entries in this book it should work. it works if I select fields from just the node table, but when I add a second table it fails. I apparently do not understand how the procedures to effect a table join work, and where I add it to the $view object. I have used the views_new_table helper function and the views_table_add_field helper function. The array that these create I have added to the views object using $view->tablename=$new_table. I have done so after exahusting many other options. I cannot find any documentation describing how the table array is associated with the view objectso after looking at code in the modules and some posts I tried this. The problem I am having is that I dont see the right table of my join in the sql query., and I get this error
=================================
user warning: Unknown column 'sales_catalog.field_prod_id_nid' in 'field list' query: SELECT DISTINCT(node.nid), node.title AS node_title, node.changed AS node_changed, sales_catalog.field_prod_id_nid AS sales_catalog_field_prod_id_nid FROM jgoa_node node WHERE (node.type = 'sales_catalog') in /home/content/c/m/o/cmould01/html/includes/database.mysql.inc on line 172.
===================================

My code is :

<?php
$tbl_sales_catalog
= views_new_table('sales_catalog', 'internal', 'node', 'nid', 'nid');
print_r($tbl_sales_catalog);

$new_table = views_table_add_field($tbl_sales_catalog, 'field_prod_id_nid', 'Prod ID', 'No Help', array(
     
'sortable' => false,
     
'handler' => 'views_handler_field_nodelink',
     
'option' => array(
        
'#type' => 'select',
        
'#options' => array(
          
'link' => 'As links',
          
'nolink' => 'Without links'
         
),
      ),
     
'notafield' => false,
    ));
//print_r($new_table);

// on the fly id and description for view
$view = views_create_view('mycustomview', 'Custom View');
// title, table view, pager on and 5 nodes-a-page... check out views.module for other params!
views_view_add_page($view, t('My Custom View'), NULL, 'table', true, 5, '', 1, false);
// we specify fields, necessary because this is a table view; first the node title
views_view_add_field($view, 'node', 'title', 'my title',false, 0'views_handler_field_nodelink');
$view->tablename=$new_table;
views_view_add_field($view, 'sales_catalog', 'field_prod_id_nid','my label',false, 0'content_views_field_handler_group');

// filters now; first, just show car dealers
views_view_add_filter($view, 'node', 'type',   '=', 'sales_catalog', '');
//views_view_add_filter($view, 'sales_catalog', 'title',   '=', 'cat001', '');
print_r($view);
// just published ones at that
views_load_cache();
views_sanitize_view($view);
print
views_build_view('embed', $view, array(), false);
?>

Any help appreciated. I realy am trying to use views and not code this with sql....But I could have done a lot more the hard way, in the time it took me to arrive at this post.

 
 

Drupal is a registered trademark of Dries Buytaert.