Skip to content

Commit

Permalink
Add an attr function to make outputting HTML attributes easier
Browse files Browse the repository at this point in the history
  • Loading branch information
mpdude committed Sep 30, 2024
1 parent b93eb3c commit c9acca6
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions extra/html-extra/HtmlExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Twig\Extra\Html;

use Symfony\Component\Mime\MimeTypes;
use Twig\Environment;
use Twig\Error\RuntimeError;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
Expand All @@ -30,6 +31,7 @@ public function getFilters(): array
{
return [
new TwigFilter('data_uri', [$this, 'dataUri']),
new TwigFilter('html_attr_merge', 'twig_html_attr_merge'),
];
}

Expand All @@ -38,6 +40,7 @@ public function getFunctions(): array
return [
new TwigFunction('html_classes', [self::class, 'htmlClasses']),
new TwigFunction('html_cva', [self::class, 'htmlCva']),
new TwigFunction('html_attr', 'twig_html_attr', ['needs_environment' => true, 'is_safe' => ['html']]),
];
}

Expand Down Expand Up @@ -124,4 +127,75 @@ public static function htmlCva(array|string $base = [], array $variants = [], ar
{
return new Cva($base, $variants, $compoundVariants, $defaultVariant);
}

static function twig_html_attr_merge(...$arrays): array
{
$result = [];

foreach ($arrays as $argNumber => $array) {
if (!$array) {
continue;
}

if (!twig_test_iterable($array)) {
throw new RuntimeError(sprintf('The "attr_merge" filter only works with arrays or "Traversable", got "%s" for argument %d.', \gettype($array), $argNumber + 1));
}

$array = twig_to_array($array);

foreach (['class', 'style', 'data'] as $deepMergeKey) {
if (isset($array[$deepMergeKey])) {
$value = $array[$deepMergeKey];
unset($array[$deepMergeKey]);

if (!twig_test_iterable($value)) {
$value = (array) $value;
}

$value = twig_to_array($value);

$result[$deepMergeKey] = array_merge($result[$deepMergeKey] ?? [], $value);
}
}

$result = array_merge($result, $array);
}

return $result;
}

static function twig_html_attr(Environment $env, ...$args): string
{
$attr = twig_html_attr_merge(...$args);

if (isset($attr['class'])) {
$attr['class'] = trim(implode(' ', array_values($attr['class'])));
}

if (isset($attr['style'])) {
$style = '';
foreach ($attr['style'] as $name => $value) {
if (is_numeric($name)) {
$style .= $value.'; ';
} else {
$style .= $name.': '.$value.'; ';
}
}
$attr['style'] = trim($style);
}

if (isset($attr['data'])) {
foreach ($attr['data'] as $name => $value) {
$attr['data-'.$name] = $value;
}
unset($attr['data']);
}

$result = '';
foreach ($attr as $name => $value) {
$result .= twig_escape_filter($env, $name, 'html_attr').'="'.htmlspecialchars($value).'" ';
}

return trim($result);
}
}

0 comments on commit c9acca6

Please sign in to comment.