Calling Views from a Custom Module

When it works the way you want, the Drupal Views module is a powerful tool. Unfortunately, you can find yourself in a situation where Views may not be able to get the information that you need. Often modules haven't integrated with Views or they are missing options you may need to get your view to work. Rather than writing up custom code for your entire feature you can use a combination of code and a view to accomplish a great result. Here's a simple way to tackle this:

First, create a simple view that accepts the content node ID (NID) as a contextual filter. Configure the rest of the view the way you need it to appear as though that NID will reference your new data.

Next, create a custom Drupal module and activate it in your site configuration. In this module, we're going to call two hooks: hook_block_info and hook_block_view.

<?php
/**
 * Implements hook_block_info
 */
function custom_module_block_info() {

  $blocks['custom_module_my_block'] = array(
    'info' => t('My block'),
    'cache' => DRUPAL_CACHE_PER_PAGE,
  );

  return $blocks;
}

/**
 * Implements hook_block_view
 *
 * Passes off the function call to _custom_module_view_DELTA
 */
function custom_module_block_view($delta = '') {
  // our block code...
}

If you activate your module before you have the block code it in, you may need to clear the Drupal cache to let the system see the new block.

Now we will create our actual block code. Since this is just an example, we'll assume we have a module that requires us to run a DB query with some information related to the current node. In this example we're also assuming this content is somehow inaccessible via Views directly. Luckily, we can still get at it and still get the benefits of using Views:

<?php

// hook_block_info

/**
 * Our block specific code
 */
function custom_module_block_view($delta = '') {
  if ($delta == ''){
    // current node
    $node = node_load(arg(1));

    // get something related from our database
    $query = db_select('some_table');
    $query
      ->fields('some_table', array('sid'))
      ->condition('some_table.nid', $node->nid, '=');
    $related_id = $query->execute()->fetchAssoc();

    // load our view and pass it
    $view = views_get_view('machine_name_for_view');
    $view->init();

    // you can change this to be the name of the display you want
    // to use
    $view->set_display('block');
    $view->set_arguments(array($related_id['sid']));
    return $view->render();
  }
}

So firstly, this code will use views_get_view to get our view and then we initialize the object. If you have multiple displays for your view, you can set that with set_display. In this example, we are passing a single ID over to the view, but you can also pass multi-value arguments. To accept multiple arguments, first change your contextual filter to allow multiple values. Then in your set_arguments call, pass your multiple arguments as a single string with a "+" separating the values.

And now you have a custom block that you can include via the Context or any other methods, but you still get to leverage the power of Drupal Views.

Drupal Planet Drupal Code

Read This Next