diff --git a/CHANGELOG b/CHANGELOG index 930da743e9e..82187ec51d9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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) diff --git a/doc/functions/html_attr.rst b/doc/functions/html_attr.rst new file mode 100644 index 00000000000..3fc14c79fbe --- /dev/null +++ b/doc/functions/html_attr.rst @@ -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', + } %} + + + {# example output: #} + +.. 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()); diff --git a/extra/html-extra/src/HtmlExtension.php b/extra/html-extra/src/HtmlExtension.php index 81868c59799..ab1b963740f 100644 --- a/extra/html-extra/src/HtmlExtension.php +++ b/extra/html-extra/src/HtmlExtension.php @@ -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']]), ]; } @@ -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 @@ -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; +} } diff --git a/extra/html-extra/tests/Fixtures/html_attr.test b/extra/html-extra/tests/Fixtures/html_attr.test new file mode 100644 index 00000000000..94fb045f171 --- /dev/null +++ b/extra/html-extra/tests/Fixtures/html_attr.test @@ -0,0 +1,15 @@ +--TEST-- +"html_attr" function +--TEMPLATE-- +{% set attr = { + 'aria-expandend': 'false', + disabled: true, + hidden: false, + id: 123, + title: 'cli"