Commit 8346a82a authored by Vit Hovezak's avatar Vit Hovezak

Issue #3056152 by artis, kyberman: Output field as a 'data-[field_name]' attribute on the entity

parent 2c089987
......@@ -4,6 +4,12 @@
Apply class on the entity if it's field is using this formatter.
**Optional configuration:**
* Prefix to be attached before each class.
* Suffix to be attached after each class.
* Attribute name to be used instead of class.
## Maintainers
This module is maintained by developers at Morpht. For more information on
......
......@@ -8,3 +8,6 @@ field.formatter.settings.entity_class_formatter:
suffix:
type: string
label: 'Suffix to be attached after each class'
attr:
type: string
label: 'Attribute name to be used instead of class'
......@@ -63,20 +63,23 @@ function entity_class_formatter_entity_view_alter(array &$build, EntityInterface
}
$field = $entity->get($name);
$field_definition = $field->getFieldDefinition();
$values = [];
// Get prefix to be attached before.
$prefix = !empty($settings['prefix']) ? $settings['prefix'] : '';
// Get suffix to be attached after.
$suffix = !empty($settings['suffix']) ? $settings['suffix'] : '';
// Get attribute name (class by default).
$attr = !empty($settings['attr']) ? $settings['attr'] : 'class';
// Only for entity reference field type.
if ($field instanceof EntityReferenceFieldItemListInterface) {
foreach ($field->referencedEntities() as $referenced_entity) {
// Fill title as a class if not empty.
// Fill title if not empty.
$title = $referenced_entity->label();
if (!empty($title)) {
$build['#attributes']['class'][] = Html::getClass($prefix . $title . $suffix);
$values[] = $prefix . $title . $suffix;
}
}
}
......@@ -84,29 +87,41 @@ function entity_class_formatter_entity_view_alter(array &$build, EntityInterface
// Only for boolean field type.
elseif ($field_definition->getType() === 'boolean') {
// Fill configured label as a class based on value.
// Fill configured label based on value.
if (filter_var($field->value, FILTER_VALIDATE_BOOLEAN)) {
$label = $field_definition->getSetting('on_label');
}
else {
$label = $field_definition->getSetting('off_label');
}
$build['#attributes']['class'][] = Html::getClass($prefix . $label . $suffix);
$values[] = $prefix . $label . $suffix;
}
// For other simple fields.
else {
foreach ($field->getValue() as $item) {
// Fill value as a class if not empty.
// Fill value if not empty.
if (!empty($item['value'])) {
// Split value into multiple classes when spaces are used.
foreach (explode(' ', $item['value']) as $class) {
$build['#attributes']['class'][] = Html::getClass($prefix . $class . $suffix);
if ($attr === 'class') {
foreach (explode(' ', $item['value']) as $class) {
$values[] = $prefix . $class . $suffix;
}
}
else {
// Provide other attribute value as it is.
$values[] = $prefix . $item['value'] . $suffix;
}
}
}
}
// Process all discovered values.
$method = $attr === 'class' ? 'getClass' : 'escape';
foreach ($values as $value) {
$build['#attributes'][$attr][] = Html::$method($value);
}
}
}
......@@ -29,6 +29,7 @@ class EntityClassFormatter extends FormatterBase {
return [
'prefix' => '',
'suffix' => '',
'attr' => '',
] + parent::defaultSettings();
}
......@@ -47,6 +48,12 @@ class EntityClassFormatter extends FormatterBase {
'#title' => $this->t('Suffix to be attached after each class'),
'#default_value' => $this->getSetting('suffix'),
];
$form['attr'] = [
'#type' => 'textfield',
'#title' => $this->t('Attribute name to be used instead of class'),
'#description' => $this->t('The field value will be escaped and assigned to the attribute you specify here (e.g. "data-value").'),
'#default_value' => $this->getSetting('attr'),
];
return $form;
}
......@@ -67,6 +74,12 @@ class EntityClassFormatter extends FormatterBase {
'@suffix' => $suffix,
]);
}
$attr = $this->getSetting('attr');
if (!empty($attr)) {
$summary[] = $this->t('Attribute: "@attr".', [
'@attr' => $attr,
]);
}
return $summary;
}
......
......@@ -46,6 +46,16 @@ class EntityClassFormatterTest extends BrowserTestBase {
*/
const CLASS_SUFFIX = '-suffix';
/**
* Define test attribute name.
*/
const ATTR_NAME = 'data-test-attr';
/**
* Define test attribute value.
*/
const ATTR_VALUE = 'test attribute value';
/**
* {@inheritdoc}
*/
......@@ -98,16 +108,38 @@ class EntityClassFormatterTest extends BrowserTestBase {
$assert_session->elementExists('css', '.node.' . $class);
}
/**
* {@inheritdoc}
*/
public function testAttrValue() {
$field_config = $this->createField('string', self::ATTR_NAME);
$entity = $this->drupalCreateNode([
$field_config->getName() => [
0 => ['value' => self::ATTR_VALUE],
],
]);
$entity->save();
$this->drupalGet($entity->toUrl());
$assert_session = $this->assertSession();
$class = self::CLASS_PREFIX . self::ATTR_VALUE . self::CLASS_SUFFIX;
$selector = '.node[' . self::ATTR_NAME . '="' . $class . '"]';
$assert_session->elementExists('css', $selector);
}
/**
* Creates a field and sets the formatter.
*
* @param string $field_type
* The type of field.
* @param string $display_attr
* The display attribute name.
*
* @return \Drupal\field\Entity\FieldConfig
* The newly created field.
*/
protected function createField($field_type) {
protected function createField($field_type, $display_attr = '') {
$entity_type = 'node';
$bundle = 'page';
$field_name = mb_strtolower($this->randomMachineName());
......@@ -137,6 +169,7 @@ class EntityClassFormatterTest extends BrowserTestBase {
'settings' => [
'prefix' => self::CLASS_PREFIX,
'suffix' => self::CLASS_SUFFIX,
'attr' => $display_attr,
],
]);
$display->save();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment