With the release of Drupal 11.3.x, the Views API has received an important change:
the long-standing access callback key used in Views handler definitions has been deprecated.
This update impacts module developers, site builders, and anyone defining custom Views handlers.
🚨 What Exactly Has Been Deprecated?
In earlier versions of Drupal, you could define access logic for a Views handler directly inside views_data():
'access callback' => 'my_module_views_access',
or even:
'access callback' => TRUE,
This approach is now deprecated and will be fully removed in a future release of Drupal 11.
After its removal, if a handler does not explicitly define the access() method,
access will default to FALSE — meaning the field, filter, or argument becomes inaccessible for most users.
✔ The New Recommended Way: Override access() in a Custom Handler
Instead of providing a callable in the Views data array, developers must now define a custom handler class and implement their own access logic.
Step 1: Register the handler in views_data()
function my_module_views_data() {
$data['node_field_data']['my_custom_field'] = [
'title' => t('My custom field'),
'help' => t('A field with custom access logic.'),
'field' => [
'id' => 'my_custom_field_handler',
],
];
return $data;
}
Step 2: Create the custom handler class
src/Plugin/views/field/MyCustomFieldHandler.php
<?php
namespace Drupal\my_module\Plugin\views\field;
use Drupal\views\Plugin\views\field\FieldPluginBase;
/
* @ViewsField("my_custom_field_handler")
*/
class MyCustomFieldHandler extends FieldPluginBase {
/
* {@inheritdoc}
*/
public function access() {
// Example: Only users with a specific permission can see this field.
$account = \Drupal::currentUser();
return $account->hasPermission('view my custom field');
}
/**
* {@inheritdoc}
*/
public function render($values) {
return ['#markup' => 'Hello world!'];
}
}
Step 3: (Optional) Add a custom permission
my_module.permissions.yml
view my custom field:
title: 'View My Custom Field'
💡 Why This Change Was Introduced
The legacy access callback approach was:
- Inconsistent with how modern plugin access is handled in Drupal
- Hard to debug (callables could be functions, class methods, etc.)
- Detached from the actual handler logic
- Difficult to statically analyze
By requiring access checks to live inside the handler class, Drupal ensures:
- Cleaner, object-oriented access control
- Predictable behavior across Views plugins
- Stronger security guarantees
- Better compatibility with future changes in the Views API
This aligns with the trend of modernizing Drupal’s plugin architecture using attributes and OOP patterns.
🧩 What Happens If You Do Nothing?
If your module still uses:
'access callback' => ...
Then:
- Drupal 11.3 will trigger a deprecation warning.
- A future release (probably Drupal 11.5 or 12.0) will remove support completely.
- Your handler's access logic will no longer run.
- Access will default to FALSE, effectively hiding the handler’s output.
📝 Summary
| Old (deprecated) | New (recommended) |
|---|---|
'access callback' => ... | Create a custom handler class |
Access logic in views_data() | Access logic inside access() method |
| Callable functions | Object-oriented permissions |
| Unpredictable behavior | Consistent plugin-based access control |
If your module defines custom Views fields, filters, or argument handlers, now is the time to refactor them.
Comments