Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
* 2.12.3 (2019-XX-XX)

* fixed number formatter in Intl extra extension when using a formatter prototype
* fixed number formatter in Intl extra extension when using a formatter prototype
* added "html_attr" function to the HtmlExtension extension in the "extra" repositories

* 2.12.2 (2019-11-11)

Expand Down
37 changes: 37 additions & 0 deletions doc/functions/html_attr.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
``html_attr``
================

.. versionadded:: 2.x
The ``html_attr`` function was added in Twig 2.x.

The ``html_attr`` function returns a string by joining html attributes together:

.. code-block:: twig

{% set attr = {
id: 123,
disabled: true,
hidden: false,
type: 'button',
'aria-expandend': 'false',
} %}
<button{{ html_attr(attr) }}></button>

{# example output: <button id="123" disabled type="button" aria-expandend="false"></button> #}

.. note::

The ``html_attr`` function is part of the ``HtmlExtension`` which is not
installed by default. Install it first:

.. code-block:: bash

$ composer req twig/html-extra

Then, use the ``twig/extra-bundle`` on Symfony projects or add the extension
explictly on the Twig environment::

use Twig\Extra\Html\HtmlExtension;

$twig = new \Twig\Environment(...);
$twig->addExtension(new HtmlExtension());
22 changes: 22 additions & 0 deletions extra/html-extra/src/HtmlExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function getFunctions()
{
return [
new TwigFunction('html_classes', 'twig_html_classes'),
new TwigFunction('html_attr', 'twig_html_attributes', ['needs_environment' => true, 'is_safe' => ['html']]),
];
}

Expand Down Expand Up @@ -83,6 +84,7 @@ public function dataUri(string $data, string $mime = null, array $parameters = [
}

namespace {
use Twig\Environment;
use Twig\Error\RuntimeError;

function twig_html_classes(...$args): string
Expand All @@ -108,4 +110,24 @@ function twig_html_classes(...$args): string

return implode(' ', array_unique($classes));
}

function twig_html_attributes(Environment $env, array $attributes): string
{
$output = '';

foreach ($attributes as $attribute => $value) {
$attribute = \htmlspecialchars($attribute, ENT_COMPAT | ENT_HTML5, $env->getCharset(), false);

if ($value === true) {
$output .= ' ' . $attribute;
} else if (\is_string($value) || \is_numeric($value)) {
$value = \htmlspecialchars($value, ENT_COMPAT | ENT_HTML5, $env->getCharset(), false);
$output .= sprintf(' %s="%s"', $attribute, $value);
} else if ($value !== false) {
throw new RuntimeError(sprintf('The html_attr function argument value of key %d should be either a boolean, string or number, got "%s".', $attribute, \gettype($value)));
}
}

return $output;
}
}
15 changes: 15 additions & 0 deletions extra/html-extra/tests/Fixtures/html_attr.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
"html_attr" function
--TEMPLATE--
{% set attr = {
'aria-expandend': 'false',
disabled: true,
hidden: false,
id: 123,
title: 'cli"<ck',
} %}
{{ html_attr(attr) }}
--DATA--
return []
--EXPECT--
aria-expandend="false" disabled id="123" title="cli&quot;&lt;ck"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
--TEST--
"html_attr" function
--TEMPLATE--
{{ html_attr({ test: { foo: 'bar' }}) }}
--DATA--
return []
--EXCEPTION--
Twig\Error\RuntimeError: The html_attr function argument value of key 0 should be either a boolean, string or number, got "array" in "index.twig" at line 2.