Problem/Motivation
There is no easy way to add an attribute (class, title, rel, target) to the anchor tag of link field unless it is of the "Separate title and URL" format. No template is provided for the default format.
From field.html.twig
template:
<div{{ attributes.addClass(classes) }}>
{% if not label_hidden %}
<div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
{% endif %}
<div{{ content_attributes.addClass('field-items') }}>
{% for item in items %}
<div{{ item.attributes.addClass('field-item') }}>{{ item.content }}</div>
{% endfor %}
</div>
</div>
item.content
contains the anchor tag of a link field.
From template_preprocess_field
:
$variables['items'] = array();
$delta = 0;
while (!empty($element[$delta])) {
$variables['items'][$delta]['content'] = $element[$delta];
// Modules (e.g., rdf.module) can add field item attributes (to
// $item->_attributes) within hook_entity_prepare_view(). Some field
// formatters move those attributes into some nested formatter-specific
// element in order have them rendered on the desired HTML element (e.g., on
// the <a> element of a field item being rendered as a link). Other field
// formatters leave them within $element['#items'][$delta]['_attributes'] to
// be rendered on the item wrappers provided by field.html.twig.
$variables['items'][$delta]['attributes'] = !empty($element['#items'][$delta]->_attributes) ? new Attribute($element['#items'][$delta]->_attributes) : clone($default_attributes);
$delta++;
}
$variables['items'][$delta]['attributes']
is rendered on the outer div <div{{ item.attributes.addClass('field-item') }}>
So the only possible way is to write a hook_entity_prepare_view
like rdf module does. Since themes can't add this hook, you have to write a custom module:
/**
* Implements hook_entity_prepare_view().
*/
function my_module_links_block_entity_prepare_view($entity_type_id, array $entities, array $displays, $view_mode) {
if ($entity_type_id == 'some_entity_type') {
foreach ($entities as $entity) {
if ($entity->bundle() == 'some_bundle') {
foreach ($displays[$entity->bundle()]->getComponents() as $name => $options) {
if ($name == 'some_link_field') {
foreach ($entity->get($name) as $item) {
$item->_attributes += array('class' => array('Yay-add-my-class'));
}
}
}
}
}
}
}
Proposed resolution
Move
https://www.drupal.org/project/link_attributes β
to core
Remaining tasks
Add tests
Updating exisitng config in post update hook
Review
User interface changes
Link widget will allow to set attributes from ui.
API changes
None