Recently I had a client who had the need to allow users to create content, but have varying levels of access to certain fields.
In this example, admin users would use Inline Entity Form to produce "Tags" on the site; however, normal "member" users were only allowed to select existing tags from an approved list of tags as checkboxes.
Drupal doesn't currently have a way to show widgets per role, so we wanted a simple, yet lightweight way to produce this. Here's what we did:
hook_entity_form_display_alter()
We alter the field based on the entity type and bundle:
php
/**
* Implements hook_entity_form_display_alter().
*/
function my_module_entity_form_display_alter(EntityFormDisplayInterface $form_display, array $context) {
// Change tags widget to checkboxes/radio buttons for members.
$bundles = ['video', 'forum', 'article', 'image'];
$entityTypes = ['node', 'media'];
if (in_array($context['entity_type'], $entityTypes) && in_array($context['bundle'], $bundles)) {
$roles = \Drupal::currentUser()->getRoles();
// Allow normal widget for admin/webadmin.
if (!count(array_intersect(['administrator', 'web_admin'], $roles))) {
$tags = $form_display->getComponent('field_tags');
$tags['settings'] = [];
$tags['type'] = 'options_buttons';
$form_display->setComponent('field_tags', $tags);
}
}
}
That's it that's all, now any role except our admin-types will see checkboxes here (since our cardinality is -1, if it were 1 they would see radios).
As a bonus, we also only allow "Approved" tags to be selected by these users. To do this we just use a form_alter() and check for if the widget has been changed and use:
$form['field_tags']['widget']['#options']
Happy altering!