Skip to content

How-to guideFor module developersDrupal 11

Extend Views with handlers

Views builds listing pages as configuration: a query plus display assembled in the admin UI. A Views handler operates on one column of data: a field displays it, a filter narrows the result set by it, a sort orders by it, an argument accepts it as a contextual filter. This guide adds a custom field handler that renders node titles in uppercase; the other handler types follow the same shape.

Make a computed or specially formatted value available in the Views UI, so site builders can add it to any view like a built-in field. If you only need to reformat an existing field’s value for display, a field formatter may be enough; reach for a handler when the logic belongs to Views (querying, filtering, sorting).

A field handler extends FieldPluginBase, which already adds the column to the query. You override render() to format the value. Put it in src/Plugin/views/field/ and give it an ID with the #[ViewsField] attribute.

web/modules/custom/howto_views/src/Plugin/views/field/UppercaseTitle.php
<?php
declare(strict_types=1);
namespace Drupal\howto_views\Plugin\views\field;
use Drupal\views\Attribute\ViewsField;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;
/**
* Renders a node title in uppercase.
*
* A field handler maps a column into a view and turns its raw value into
* output. The base class adds the column to the query; you override
* render() to format it.
*/
#[ViewsField('howto_uppercase')]
final class UppercaseTitle extends FieldPluginBase {
/**
* {@inheritdoc}
*/
public function render(ResultRow $values): string {
return mb_strtoupper((string) $this->getValue($values));
}
}

getValue() returns the raw value of the column the handler is bound to; render() returns what appears in the cell.

A handler is invisible until Views data advertises it. Implement hook_views_data_alter() as an object-oriented hook to attach the field to a table, naming the handler’s plugin ID and the real column it reads.

web/modules/custom/howto_views/src/Hook/HowtoViewsHooks.php
/**
* Registers the custom field handler against the node title column.
*/
#[Hook('views_data_alter')]
public function viewsDataAlter(array &$data): void {
$data['node_field_data']['howto_uppercase_title'] = [
'title' => $this->t('Title (uppercase)'),
'help' => $this->t('The node title rendered in uppercase.'),
'field' => [
'id' => 'howto_uppercase',
// The real column the handler reads.
'real field' => 'title',
],
];
}

After a cache rebuild (drush cr), “Title (uppercase)” appears in the field list for any view on content.

The example module ships a view that uses the handler. After installing it:

Terminal window
ddev drush pm:install howto_views
ddev drush php:eval "
\$v = \Drupal\views\Views::getView('howto_uppercase_titles');
\$v->execute();
echo \$v->field['howto_uppercase_title']->render(\$v->result[0]);
"

prints the first node’s title in uppercase. The module’s kernel test asserts the same end to end.

Each handler family has its own base class and directory, and registers under its own key in Views data:

HandlerBase classDirectoryViews-data key
FieldFieldPluginBasesrc/Plugin/views/fieldfield
FilterFilterPluginBasesrc/Plugin/views/filterfilter
SortSortPluginBasesrc/Plugin/views/sortsort
ArgumentArgumentPluginBasesrc/Plugin/views/argumentargument

A filter overrides query() to add a WHERE condition; a sort adds ORDER BY; an argument turns a URL segment into a condition.

Was this page helpful?

Drupal is a registered trademark of Dries Buytaert.