twig_attributes-8.x-1.x-dev/src/TwigExtension.php
src/TwigExtension.php
<?php
namespace Drupal\twig_attributes;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Render\Element;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
/**
* Defines Twig extensions.
*/
class TwigExtension extends AbstractExtension {
/**
* {@inheritdoc}
*/
public function getFilters() {
return [
new TwigFilter('add_attr', [$this, 'addAttributes']),
new TwigFilter('with_attr', [$this, 'addAttributes']),
];
}
/**
* Add attributes to a renderable array.
*
* @param array $build
* The renderable array.
* @param string $key
* The key of the element to which the attributes should be added.
* @param string|array $attributes
* The attributes to add.
* @param bool $add_to_children
* Whether the attributes should be added to the array's children.
* @param bool $overwrite
* Whether the attributes should be overwritten instead of merged.
*
* @return array
* The altered renderable array.
*/
public function addAttributes(array $build, $key, $attributes, $add_to_children = TRUE, $overwrite = FALSE) {
// Make sure the key starts with a hash, so it's treated as a property.
if (strpos($key, '#') !== 0) {
$key = '#' . $key;
}
if ($add_to_children) {
foreach (Element::children($build) as $child_key) {
$build[$child_key] = $this->addAttributes($build[$child_key], $key, $attributes, FALSE, $overwrite);
}
return $build;
}
// Set the default existing value and new value.
$existing_value = NULL;
$new_value = $attributes;
// Get any existing value.
if (!$overwrite && isset($build[$key])) {
$existing_value = $build[$key];
}
// Merge values if necessary.
if (is_array($existing_value)) {
if (!is_array($attributes)) {
$attributes = [$attributes];
}
$new_value = NestedArray::mergeDeepArray([$existing_value, $attributes]);
}
// Set the new value.
$build[$key] = $new_value;
// Special treatment of the "link" template.
if (isset($build['#type']) && $build['#type'] == 'link' && isset($build['#link_attributes'])) {
if (!isset($build['#options']['attributes'])) {
$build['#options']['attributes'] = [];
}
$build['#options']['attributes'] = array_merge($build['#options']['attributes'], $build['#link_attributes']);
}
return $build;
}
}
