How to Easily Create Drupal Views in Code

Scott Reynen

Just a couple months ago the title of this post would have sounded crazy to me.

For the last several months I've been working on the CINC module as a way to make my work (and yours) with Drupal configuration better: faster, more predictable, more flexible, etc. Views is one of the most complex types of Drupal configuration, and I've been doing a great job of delaying what I saw as a daunting challenge of figuring out how Views should work with CINC. Even a simple Views export makes it clear that as you click around the Views UI, a lot is happening in the code, and it can be difficult to understand what exactly is going on. Here's an example Views export:

$view = new view();
$view->name = 'random_instructor';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Random Instructor';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
 
/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'none';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'some';
$handler->display->display_options['pager']['options']['items_per_page'] = '1';
$handler->display->display_options['pager']['options']['offset'] = '0';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'node';
/* Sort criterion: Global: Random */
$handler->display->display_options['sorts']['random']['id'] = 'random';
$handler->display->display_options['sorts']['random']['table'] = 'views';
$handler->display->display_options['sorts']['random']['field'] = 'random';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'instructor' => 'instructor',
);
 
/* Display: Block */
$handler = $view->new_display('block', 'Block', 'block');

That view shows one random instructor node in a block. And if you read the code for a few minutes, you can probably figure that out. But I don't know anyone who would attempt to write that code from scratch. So the only way to create a view like that is to click around in the Views UI. As impressive as the Views UI is, clicking a dozen times and finding the few options I care about among the dozens I don't is still an incredibly tedious way to say "show one random instructor node in a block." Ideally I would say that with code that looks more like show_one_random_instructor_node_in_a_block(); I should be able to say what I want and move on to thinking about more interesting problems, without slowing down on implementation details for simple needs.

As of the beta 2 release, CINC has Views integration, and it's wonderful. It's not quite as simple as show_one_random_instructor_node_in_a_block(), but here's how I'm currently creating that Views block:

CINC::init('View')->machine_name('random_instructor')
  ->set('human_name', 'Random Instructor')
  ->set_row_style('node')
  ->set_view_mode('teaser')
  ->add_filter('published')
  ->add_node_type_filter('instructor')
  ->limit_items(1)
  ->add_sort('random')
  ->add_block_display()
  ->create();

So far that's only touching a small subset of what Views can do. I'll continue refining CINC Views toward this "say what you want and move on" ideal. But now that it's good enough that I'm personally no longer using Views UI at all, I wanted to invite you to the party.

Writing Views configuration from scratch is no longer daunting, and it will only get easier from here. So try it out and submit your own requests to make it even better.