diff --git a/doc/coding_standards.rst b/doc/coding_standards.rst
index d10906fa6..46be8eca6 100644
--- a/doc/coding_standards.rst
+++ b/doc/coding_standards.rst
@@ -105,3 +105,9 @@ standards:
true
{% endif %}
{% endblock %}
+
+* Use ``:`` instead of ``=`` to separate argument names and values:
+
+ .. code-block:: twig
+
+ {{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}
diff --git a/doc/filters/data_uri.rst b/doc/filters/data_uri.rst
index 131a71bb8..a68deb0f2 100644
--- a/doc/filters/data_uri.rst
+++ b/doc/filters/data_uri.rst
@@ -11,13 +11,13 @@ The ``data_uri`` filter generates a URL using the data scheme as defined in
{{ source('path_to_image')|data_uri }}
{# force the mime type, disable the guessing of the mime type #}
- {{ image_data|data_uri(mime="image/svg") }}
+ {{ image_data|data_uri(mime: "image/svg") }}
{# also works with plain text #}
- {{ 'foobar'|data_uri(mime="text/html") }}
+ {{ 'foobar'|data_uri(mime: "text/html") }}
{# add some extra parameters #}
- {{ 'foobar'|data_uri(mime="text/html", parameters={charset: "ascii"}) }}
+ {{ 'foobar'|data_uri(mime: "text/html", parameters: {charset: "ascii"}) }}
.. note::
diff --git a/doc/filters/format_currency.rst b/doc/filters/format_currency.rst
index 8b649bf5d..c4c364a00 100644
--- a/doc/filters/format_currency.rst
+++ b/doc/filters/format_currency.rst
@@ -45,7 +45,7 @@ By default, the filter uses the current locale. You can pass it explicitly:
.. code-block:: twig
{# 1.000.000,00 € #}
- {{ '1000000'|format_currency('EUR', locale='de') }}
+ {{ '1000000'|format_currency('EUR', locale: 'de') }}
.. note::
diff --git a/doc/filters/format_datetime.rst b/doc/filters/format_datetime.rst
index 3ca9f0be6..9caf1992c 100644
--- a/doc/filters/format_datetime.rst
+++ b/doc/filters/format_datetime.rst
@@ -16,13 +16,13 @@ You can tweak the output for the date part and the time part:
.. code-block:: twig
{# 23:39 #}
- {{ '2019-08-07 23:39:12'|format_datetime('none', 'short', locale='fr') }}
+ {{ '2019-08-07 23:39:12'|format_datetime('none', 'short', locale: 'fr') }}
{# 07/08/2019 #}
- {{ '2019-08-07 23:39:12'|format_datetime('short', 'none', locale='fr') }}
+ {{ '2019-08-07 23:39:12'|format_datetime('short', 'none', locale: 'fr') }}
{# mercredi 7 août 2019 23:39:12 UTC #}
- {{ '2019-08-07 23:39:12'|format_datetime('full', 'full', locale='fr') }}
+ {{ '2019-08-07 23:39:12'|format_datetime('full', 'full', locale: 'fr') }}
Supported values are: ``none``, ``short``, ``medium``, ``long``, ``full``,
``relative_short``, ``relative_medium``, ``relative_long``, and
@@ -34,7 +34,7 @@ For greater flexibility, you can even define your own pattern
.. code-block:: twig
{# 11 oclock PM, GMT #}
- {{ '2019-08-07 23:39:12'|format_datetime(pattern="hh 'oclock' a, zzzz") }}
+ {{ '2019-08-07 23:39:12'|format_datetime(pattern: "hh 'oclock' a, zzzz") }}
Locale
------
@@ -44,7 +44,7 @@ By default, the filter uses the current locale. You can pass it explicitly:
.. code-block:: twig
{# 7 août 2019 23:39:12 #}
- {{ '2019-08-07 23:39:12'|format_datetime(locale='fr') }}
+ {{ '2019-08-07 23:39:12'|format_datetime(locale: 'fr') }}
Timezone
--------
@@ -55,14 +55,14 @@ it by explicitly specifying a timezone:
.. code-block:: twig
- {{ datetime|format_datetime(locale='en', timezone='Pacific/Midway') }}
+ {{ datetime|format_datetime(locale: 'en', timezone: 'Pacific/Midway') }}
If the date is already a DateTime object, and if you want to keep its current
timezone, pass ``false`` as the timezone value:
.. code-block:: twig
- {{ datetime|format_datetime(locale='en', timezone=false) }}
+ {{ datetime|format_datetime(locale: 'en', timezone: false) }}
The default timezone can also be set globally by calling ``setTimezone()``::
diff --git a/doc/filters/format_number.rst b/doc/filters/format_number.rst
index 994404e07..900fa5ea9 100644
--- a/doc/filters/format_number.rst
+++ b/doc/filters/format_number.rst
@@ -44,10 +44,10 @@ Besides plain numbers, the filter can also format numbers in various styles:
.. code-block:: twig
{# 1,234% #}
- {{ '12.345'|format_number(style='percent') }}
+ {{ '12.345'|format_number(style: 'percent') }}
{# twelve point three four five #}
- {{ '12.345'|format_number(style='spellout') }}
+ {{ '12.345'|format_number(style: 'spellout') }}
{# 12 sec. #}
{{ '12'|format_duration_number }}
@@ -85,7 +85,7 @@ By default, the filter uses the current locale. You can pass it explicitly:
.. code-block:: twig
{# 12,345 #}
- {{ '12.345'|format_number(locale='fr') }}
+ {{ '12.345'|format_number(locale: 'fr') }}
.. note::
diff --git a/doc/filters/trim.rst b/doc/filters/trim.rst
index 238928bc7..ba01cbe85 100644
--- a/doc/filters/trim.rst
+++ b/doc/filters/trim.rst
@@ -14,7 +14,7 @@ and end of a string:
{# outputs ' I like Twig' #}
- {{ ' I like Twig. '|trim(side='left') }}
+ {{ ' I like Twig. '|trim(side: 'left') }}
{# outputs 'I like Twig. ' #}
diff --git a/doc/templates.rst b/doc/templates.rst
index 2746d90f6..638535614 100644
--- a/doc/templates.rst
+++ b/doc/templates.rst
@@ -210,11 +210,16 @@ built-in functions.
Named Arguments
---------------
-Named arguments are supported in functions, filters and tests.
+Named arguments are supported in functions, filters, and tests.
+
+.. versionadded:: 3.12
+
+ Twig supports both ``=`` and ``:`` as separators between argument names and
+ values, but support for ``:`` was introduced in Twig 3.12.
.. code-block:: twig
- {% for i in range(low=1, high=10, step=2) %}
+ {% for i in range(low: 1, high: 10, step: 2) %}
{{ i }},
{% endfor %}
@@ -227,7 +232,7 @@ the values you pass as arguments:
{# versus #}
- {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }}
+ {{ data|convert_encoding(from: 'iso-2022-jp', to: 'UTF-8') }}
Named arguments also allow you to skip some arguments for which you don't want
to change the default value:
@@ -238,19 +243,19 @@ to change the default value:
{{ "now"|date(null, "Europe/Paris") }}
{# or skip the format value by using a named argument for the time zone #}
- {{ "now"|date(timezone="Europe/Paris") }}
+ {{ "now"|date(timezone: "Europe/Paris") }}
You can also use both positional and named arguments in one call, in which
case positional arguments must always come before named arguments:
.. code-block:: twig
- {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }}
+ {{ "now"|date('d/m/Y H:i', timezone: "Europe/Paris") }}
.. tip::
- Each function and filter documentation page has a section where the names
- of all arguments are listed when supported.
+ Each function, filter, and test documentation page has a section where the
+ names of all supported arguments are listed.
Control Structure
-----------------
diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php
index 0055e643d..ae210ed6e 100644
--- a/src/ExpressionParser.php
+++ b/src/ExpressionParser.php
@@ -611,7 +611,7 @@ class ExpressionParser
}
$name = null;
- if ($namedArguments && $token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) {
+ if ($namedArguments && (($token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) || ($token = $stream->nextIf(Token::PUNCTUATION_TYPE, ':')))) {
if (!$value instanceof NameExpression) {
throw new SyntaxError(\sprintf('A parameter name must be a string, "%s" given.', $value::class), $token->getLine(), $stream->getSourceContext());
}
diff --git a/tests/Fixtures/functions/attribute.test b/tests/Fixtures/functions/attribute.test
index 2f70b08a4..31cca8c46 100644
--- a/tests/Fixtures/functions/attribute.test
+++ b/tests/Fixtures/functions/attribute.test
@@ -3,10 +3,12 @@
--TEMPLATE--
{{ attribute(obj, method) }}
{{ attribute(variable=obj, attribute=method) }}
+{{ attribute(variable: obj, attribute: method) }}
{{ attribute(array, item) }}
{{ attribute(obj, "bar", ["a", "b"]) }}
{{ attribute(obj, "bar", arguments) }}
{{ attribute(variable=obj, attribute="bar", arguments=arguments) }}
+{{ attribute(variable: obj, attribute: "bar", arguments: arguments) }}
{{ attribute(obj, method) is defined ? 'ok' : 'ko' }}
{{ attribute(obj, nonmethod) is defined ? 'ok' : 'ko' }}
--DATA--
@@ -14,9 +16,11 @@ return ['obj' => new Twig\Tests\TwigTestFoo(), 'method' => 'foo', 'array' => ['f
--EXPECT--
foo
foo
+foo
bar
bar_a-b
bar_a-b
bar_a-b
+bar_a-b
ok
ko
diff --git a/tests/Fixtures/functions/date_namedargs.test b/tests/Fixtures/functions/date_namedargs.test
index 11f60ee8b..819e8326b 100644
--- a/tests/Fixtures/functions/date_namedargs.test
+++ b/tests/Fixtures/functions/date_namedargs.test
@@ -3,9 +3,11 @@
--TEMPLATE--
{{ date(date, "America/New_York")|date('d/m/Y H:i:s P', false) }}
{{ date(timezone="America/New_York", date=date)|date('d/m/Y H:i:s P', false) }}
+{{ date(timezone: "America/New_York", date: date)|date('d/m/Y H:i:s P', false) }}
--DATA--
date_default_timezone_set('UTC');
return ['date' => mktime(13, 45, 0, 10, 4, 2010)]
--EXPECT--
04/10/2010 09:45:00 -04:00
04/10/2010 09:45:00 -04:00
+04/10/2010 09:45:00 -04:00