So, this stumped me for a while. I needed my small custom Drupal module to select a bunch of nodes based on a CCK Date field and the Publish status. It is a pain to query the CCK tables directly, so every forum post I could find told me to do this via Views. That’s all well and good, but the instructions for doing this all involved creating a View with the Vuiews UI, then calling it to make my query.
But I wanted to have some of the View’s query parameters change dynamically based on my module’s admin settings. Although you could probably do this with some custom Views Argument PHP code, I didn’t want to do it this way. It divorced the code from my module too much somehow. It would mean that after I installed my module I would have to create a View and paste in some custom PHP code! Yuck.
Looking through the Views 2 documentation I learned how to create “default views” for a module, but still I didn’t like this approach. This would mean that the custom view would still appear in the Views list, and could be disabled, modified, and what have you. What I really wanted to do was just create a View programmatically in my module code. How hard could it be?
Some poking around in the Views code showed me the way, however, and it turns out it’s pretty easy after all.
Basically, all you need to do is create a view using the Views UI then Export it to get most of the code. You can’t quite use the exported code as-is though. You need to replace the first line of the export code ($view = new view;) with ($view = viewsnewview();). It basically does the same thing. Once you’ve replaced that line you can create a view anywhere you want in your module’s code. You can then execute, embed it, or whatever you want by calling the appropriate functions (like $view→execute_display(‘default’, array())). Here is a piece of example code using a simple view that displays the Title field of all Published nodes:
//create a new view $view = views_new_view(); //define the view (this code was generated by the Export) $view->name = 'test_date_view'; $view->description = ''; $view->tag = ''; $view->view_php = ''; $view->base_table = 'node'; $view->is_cacheable = FALSE; $view->api_version = 2; $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ $handler = $view->new_display('default', 'Defaults', 'default'); $handler->override_option('fields', array( 'title' => array( 'label' => 'Title', 'alter' => array( 'alter_text' => 0, 'text' => '', 'make_link' => 0, 'path' => '', 'alt' => '', 'prefix' => '', 'suffix' => '', 'help' => '', 'trim' => 0, 'max_length' => '', 'word_boundary' => 1, 'ellipsis' => 1, 'html' => 0, ), 'link_to_node' => 1, 'exclude' => 0, 'id' => 'title', 'table' => 'node', 'field' => 'title', 'relationship' => 'none', ), )); $handler->override_option('filters', array( 'status' => array( 'operator' => '=', 'value' => '1', 'group' => '0', 'exposed' => FALSE, 'expose' => array( 'operator' => FALSE, 'label' => '', ), 'id' => 'status', 'table' => 'node', 'field' => 'status', 'relationship' => 'none', ), ), )); $handler->override_option('access', array( 'type' => 'none', )); $handler->override_option('cache', array( 'type' => 'none', )); $handler->override_option('row_options', array( 'inline' => array(), 'separator' => '', )); // now output the view (or whatever you want to do with it) print $view->execute_display('default', array());
I posted this over in the Drupal documentation as well.