Database independent Views 3 custom field handlers

Views has so many convenient field handlers that almost all use cases can be covered using the standard set however there are times when you may need to display custom or specially formatted data in a view row without resorting to template hacking or views hooking.

Avoid using 'Global:
custom text' fields for dynamic content

The most convincing use case of 'Global: Custom text' fields to me is combining previously added fields together in a rewrite to be displayed as a single field (for example combing a first name and last name field) however too often custom fields are used for bad practice, messy and performance intensive view manipulation. Countless times I've seen custom text fields used as placeholders for dynamic content that would be later added using various pre_render / post_render / preprocess views hooks (I've been guilty of it) instead of developers implementing custom views field handlers. So what's the alternative? Well it turns out it's easy to create a lightweight, custom, fit for purpose views custom field handler that outputs virtually any content you want it to.
/** * DO NOT USE THIS CODE * * Substituting custom field content in views hooks is a great way * to make enemies with future developers. */ function my_confusing_module_views_pre_render(&$view) { // This is messy and hard to understand for site builders and future developers. $view->result[0]->custom_field_999 = t('Foo'); }

Creating a custom views field handler

Views field handlers are defined using PHP classes that extend views_handler_field or a subclass of it. To create a views handler class:
  1. Create a custom module (if you don't know how visit http://interactivejunky.com/blog/super-simple-custom-module).
  2. Create a folder inside your custom module called includes and add a new file called views_handler_my_custom_field.inc .
  3. Copy the code below into the file to create a basic skeleton for your handler.
  4. In your modules .info file add the line files[] = includes/views_handler_my_custom_field.inc.
/** * @file * Custom views handler definition. * * Place this code in * /sites/all/[custom_module_name]/includes/views_handler_my_custom_field.inc */ /** * Custom handler class. * * @ingroup views_field_handlers */ class views_handler_my_custom_field extends views_handler_field { /** * {@inheritdoc} * * Perform any database or cache data retrieval here. In this example there is * none. */ function query() { } /** * {@inheritdoc} * * Modify any end user views settings here. Debug $options to view the field * settings you can change. */ function option_definition() { $options = parent::option_definition(); return $options; } /** * {@inheritdoc} * * Make changes to the field settings form seen by the end user when adding * your field. */ function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); } /** * Render callback handler. * * Return the markup that will appear in the rendered field. */ function render($values) { return t('Some custom markup'); } }

Defining your custom view handler

In order for views to acknowledge the existence of your views handler you'll need to define it within a file called my_custom_module.views.inc in the root module directory.
/** * Implements hook_views_data(). */ function my_custom_module_views_data() { $data['my_custom_module']['table']['group'] = t('My custom module'); $data['my_custom_module']['table']['join'] = array( // Exist in all views. '#global' => array(), ); $data['my_custom_module']['my_custom_field'] = array( 'title' => t('My custom field'), 'help' => t('My custom field displays the word "Some custom markup".'), 'field' => array( 'handler' => 'views_handler_my_custom_field', ), ); return $data; }

Telling views about your module

Finally, for views to pick up your newly created include file, you'll have to invoke the Views API hook in your .module file. You can optionally specify folders within your module for views to look in if you wish, however if you're storing the my_custom_module.views.inc file within your root module folder you only need to include the following code.
/** * Implements hook_views_api(). */ function my_custom_module_views_api() { return array( 'api' => 3, ); }

Add your custom field to a view

Before you continue, clear the Drupal cache so that the last two steps have been picked up by Views. Next visit the view you want to edit (or create a new one) and, when adding a field, your custom field should appear in the list. Simple!