Create list view in custom module (part 1)

In our EK management tools suite we have custom designed lists of items like for instance list of management documents.

Those lists are build with custom codes and templates which is somehow more convenient to manage with complex data, links, menus and filters as in the example below.

Example of documents list

 

However for simple list, the views module is very useful and can be integrated in a custom module as well to automatically create the list.

Here is an example with companies list in the system address book module showing the company name as link and a field about the type of record plus a simple filter box.

List companies

To achieve this, you need first to reference the data into your module called for instance MyModule.

The sample table structure containing the data is as follow:


    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100) NOT NULL DEFAULT '',
    `type` VARCHAR(5) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)

 

The field `type` in our case is a numeral from 1 to 3 that maps to defined description (Here we will use 1 => blue, 2 => green and 3 => red).


In MyModule.module file in our custom module, we reference those data to be accessible in views with MyModule_views_data() function.

In this function, we declare the following information:

 


/**
 * @file
 * MyModule module .
 */

function MyModule_views_data() {
  // This write hook_views_data() for the main table

  // First, the entry $data['mymodule_tb']['table'] describes properties of
  // the actual table – not its content.

  $data['mymodule_tb']['table']['group'] = t('My Module');

  // Define this as a base table
  $data['mymodule_tb']['table']['base'] = array(
    'field' => 'id', // This is the identifier field for the view.
    'title' => t('My Module'),
    'help' => t('My Module contains some data.'),
    'database' => 'external_db',
    'weight' => -10,
  );

  // This table references the {_tb_2} table. The declaration below creates an
  // 'implicit' relationship to the _tb_2 table
  $data['mymodule_tb']['table']['join'] = array(
    'database' => 'external_db',
    'mymodule_tb_2' => array(
      'left_field' => 'mid',
      'field' => 'id',
      'database' => 'external_db',
    ),
  );

  // Next, describe each of the individual fields in this table to Views.
  //  ID table field.
  $data['mymodule_tb']['id'] = array(
    'title' => t('mymodule_tb id'),
    'help' => t('mymodule_tb id.'),
    'relationship' => array(
      'base' => 'mymodule_tb_2', // The name of the table to join with
      'field' => 'mid', // The name of the field to join with
      'id' => 'standard',
      'label' => t('linked table to mymodule_tb'),
    ),
        'field' => array(
      'id' => 'numeric',
    ),
    'sort' => array(
      'id' => 'standard',
    ),
    'filter' => array(
      'id' => 'numeric',
    ),
  );

  // Example plain text field.
  $data['mymodule_tb']['name'] = array(
    'title' => t('name'),
    'help' => t('entry name.'),
    'field' => array(
      'id' => 'standard',
    ),
    'sort' => array(
      'id' => 'standard',
    ),
    'filter' => array(
      'id' => 'string',
    ),
    'argument' => array(
      'id' => 'string',
    ),
  );
 
  $data['mymodule_tb']['type'] = array(
    'title' => t('type'),
    'help' => t('type: 1 blue, 2 green, 3 red'),
    'field' => array(
      'id' => 'numeric',
    ),
    'sort' => array(
      'id' => 'standard',
    ),
    'filter' => array(
      'id' => 'numeric',
    ),
  );  

// This write hook_views_data() for the linked table


$data['mymodule_tb_2']['table']['group'] = t('My Module table 2');

  $data['mymodule_tb_2']['table']['base'] = array(
    'field' => 'id', // This is the identifier field for the view.
    'title' => t('My Module table 2'),
    'help' => t('My Module tb_2 contains linked data to mymodule_tb.'),
    'weight' => -10,
    'database' => 'external_db',
  );

  $data['mymodule_tb_2']['table']['join'] = array(
    'mymodule_tb' => array(
      'left_field' => 'id',
      'field' => 'mid',
      'database' => 'external_db',
    ),
  );

  //  ID table field.
  $data['mymodule_tb_2']['id'] = array(
    'title' => t('tb_2 id'),
    'help' => t('tb_2 id.'),
       'field' => array(
       'id' => 'numeric',
    ),
       'sort' => array(
       'id' => 'standard',
    ),
       'filter' => array(
       'id' => 'numeric',
    ),
  );
 
  $data['mymodule_tb_2']['mid'] = array(
    'title' => t('mymodule_tb id'),
    'help' => t('mymodule_tb id ref.'),
    'relationship' => array(
      'base' => 'mymodule_tb',
      'field' => 'id',
      'id' => 'standard',
      'label' => t('mymodule_tb entry'),
    ),
       'field' => array(
       'id' => 'numeric',
    ),
       'sort' => array(
       'id' => 'standard',
    ),
       'filter' => array(
       'id' => 'numeric',
    ),
  );


  $data['mymodule_tb_2']['comment'] = array(
    'title' => t('comment'),
    'help' => t('linked comment.'),
    'field' => array(
      'id' => 'standard',
    ),
    'sort' => array(
      'id' => 'standard',
    ),
    'filter' => array(
      'id' => 'string',
    ),
    'argument' => array(
      'id' => 'string',
    ),
  );
  return $data;
}

 

Few remarks about the above information:

  • In this example, we have a table linked to our main table which is described by $data['mymodule_tb']['table']['join'] and  $data['mymodule_tb_2']['table']['join']
  • The dabase containing the data is specified as 'external_db'. In our configuration, we do not use the default database of Drupal installation (this database must be defined in settings.php).

 

If we navigate to "/admin/structure/views/add", we can now create a view based on our main table content:

My Module view

 

In the next article we will describe how to create the page similar to our address book list view with specific rewrite results for "type" field and filter criterion.

Feel free to add your own comments or suggestions.

 

Comments

Thanks for posting this interesting information. I have always thought that creating custom data tables in Drupal should be easier. Some type of information / recordings does not need to enter the big realm of nodes or entities. Would be nice to learn how to easily insert data to those custom data tables within the Drupal API itself.

Add new comment

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.