From bd33033fd18761be616f52757834cc0a1c32acab Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Fri, 27 Sep 2024 10:46:21 +0200 Subject: [PATCH 1/6] Update plural.rst: Fixing filter name Info is taken from https://github.com/twigphp/Twig/pull/4357#issuecomment-2378435199 Besides, I changed to a more illustrative example word. One of the rare cases where ChatGPT was indeed useful... ;-) --- doc/filters/plural.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/filters/plural.rst b/doc/filters/plural.rst index 50c18cdc0..770345219 100644 --- a/doc/filters/plural.rst +++ b/doc/filters/plural.rst @@ -11,11 +11,11 @@ plural version: .. code-block:: twig {# English (en) rules are used by default #} - {{ 'partition'|pluralize() }} - partitions + {{ 'animal'|plural() }} + animals - {{ 'partition'|pluralize('fr') }} - partitions + {{ 'animal'|plural('fr') }} + animaux .. note:: From fae6cfc32f3867fdfd98ff7def9c8ffb6df4dbd4 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 28 Sep 2024 09:21:06 +0200 Subject: [PATCH 2/6] Add more information about the filter and the negative operators --- doc/templates.rst | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/doc/templates.rst b/doc/templates.rst index 0cd909225..b87ee1ed7 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -122,9 +122,9 @@ You can assign values to variables inside code blocks. Assignments use the Filters ------- -Variables can be modified by **filters**. Filters are separated from the -variable by a pipe symbol (``|``). Multiple filters can be chained. The output -of one filter is applied to the next. +Variables and expressions can be modified by **filters**. Filters are separated +from the variable by a pipe symbol (``|``). Multiple filters can be chained. +The output of one filter is applied to the next. The following example removes all HTML tags from the ``name`` and title-cases it: @@ -152,6 +152,37 @@ To apply a filter on a section of code, wrap it with the Go to the :doc:`filters` page to learn more about built-in filters. +.. warning:: + + As the ``filter`` operator has the highest :ref:`precedence + `, use parentheses when filtering more "complex" + expressions: + + .. code-block:: twig + + {{ (1..5)|join(', ') }} + + {{ ('HELLO' ~ 'FABIEN')|lower }} + + A common mistake is to forget using parentheses for filters on negative + numbers as a negative number in Twig is represented by the ``-`` operator + followed by a positive number. As the ``-`` operator has a lower precedence + than the filter operator, it leads to confusion: + + .. code-block:: twig + + {{ -1|abs }} {# returns -1 #} + + {# as it is equivalent to #} + + {{ -(1|abs) }} + + For such cases, use parentheses to force the precedence: + + .. code-block:: twig + + {{ (-1)|abs }} {# returns 1 as expected #} + Functions --------- @@ -795,7 +826,7 @@ The following operators don't fit into any of the other categories: .. code-block:: twig - (1..5)|join(', ') + {{ (1..5)|join(', ') }} * ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello From 871639260384ac0c8f4e32154839dc56863e0816 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Jan 2024 12:26:39 +0100 Subject: [PATCH 3/6] Added details in the doc of filters and functions of IntlExtension --- doc/filters/country_name.rst | 12 +++++++++++- doc/filters/currency_name.rst | 7 +++++-- doc/filters/currency_symbol.rst | 7 +++++-- doc/filters/format_currency.rst | 5 ++++- doc/filters/format_date.rst | 5 ++++- doc/filters/format_datetime.rst | 4 +++- doc/filters/format_number.rst | 5 ++++- doc/filters/format_time.rst | 5 ++++- doc/filters/language_name.rst | 9 ++++++--- doc/filters/locale_name.rst | 8 +++++--- doc/filters/slug.rst | 5 ++++- doc/filters/timezone_name.rst | 7 +++++-- doc/functions/country_names.rst | 5 ++++- doc/functions/country_timezones.rst | 9 ++++++++- doc/functions/currency_names.rst | 5 ++++- doc/functions/language_names.rst | 5 ++++- doc/functions/locale_names.rst | 5 ++++- doc/functions/script_names.rst | 5 ++++- doc/functions/timezone_names.rst | 5 ++++- 19 files changed, 92 insertions(+), 26 deletions(-) diff --git a/doc/filters/country_name.rst b/doc/filters/country_name.rst index 434b0bda7..394e9f5b7 100644 --- a/doc/filters/country_name.rst +++ b/doc/filters/country_name.rst @@ -16,6 +16,13 @@ By default, the filter uses the current locale. You can pass it explicitly: {# États-Unis #} {{ 'US'|country_name('fr') }} +The locale can contain more than two letters depending on the region: + +.. code-block:: twig + + {# 美國 #} + {{ 'US'|country_name('zh_Hant_HK') }} + .. note:: The ``country_name`` filter is part of the ``IntlExtension`` which is not @@ -41,4 +48,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/currency_name.rst b/doc/filters/currency_name.rst index a35c49998..9c8aba2a2 100644 --- a/doc/filters/currency_name.rst +++ b/doc/filters/currency_name.rst @@ -1,7 +1,7 @@ ``currency_name`` ================= -The ``currency_name`` filter returns the currency name given its three-letter +The ``currency_name`` filter returns the currency name given its ISO 4217 three-letter code: .. code-block:: twig @@ -44,4 +44,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/filters/currency_symbol.rst b/doc/filters/currency_symbol.rst index 84a048ed5..716a7f310 100644 --- a/doc/filters/currency_symbol.rst +++ b/doc/filters/currency_symbol.rst @@ -1,7 +1,7 @@ ``currency_symbol`` =================== -The ``currency_symbol`` filter returns the currency symbol given its three-letter +The ``currency_symbol`` filter returns the currency symbol given its ISO 4217 three-letter code: .. code-block:: twig @@ -44,4 +44,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/filters/format_currency.rst b/doc/filters/format_currency.rst index 8b649bf5d..6c140f951 100644 --- a/doc/filters/format_currency.rst +++ b/doc/filters/format_currency.rst @@ -74,4 +74,7 @@ Arguments * ``currency``: The currency * ``attrs``: A map of attributes -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/filters/format_date.rst b/doc/filters/format_date.rst index cd6beba9f..c36748ecc 100644 --- a/doc/filters/format_date.rst +++ b/doc/filters/format_date.rst @@ -29,8 +29,11 @@ the :doc:`format_datetime` filter, but without the time. Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. * ``dateFormat``: The date format * ``pattern``: A date time pattern * ``timezone``: The date timezone * ``calendar``: The calendar ("gregorian" by default) + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/format_datetime.rst b/doc/filters/format_datetime.rst index 8f3b46d47..085af1294 100644 --- a/doc/filters/format_datetime.rst +++ b/doc/filters/format_datetime.rst @@ -98,7 +98,7 @@ The default timezone can also be set globally by calling ``setTimezone()``:: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. * ``dateFormat``: The date format * ``timeFormat``: The time format * ``pattern``: A date time pattern @@ -106,3 +106,5 @@ Arguments * ``calendar``: The calendar ("gregorian" by default) .. _ICU user guide: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/format_number.rst b/doc/filters/format_number.rst index a1c2804ab..301b10348 100644 --- a/doc/filters/format_number.rst +++ b/doc/filters/format_number.rst @@ -112,6 +112,9 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. * ``attrs``: A map of attributes * ``style``: The style of the number output + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/format_time.rst b/doc/filters/format_time.rst index 1e213e616..25710e5ce 100644 --- a/doc/filters/format_time.rst +++ b/doc/filters/format_time.rst @@ -29,8 +29,11 @@ the :doc:`format_datetime` filter, but without the date. Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. * ``timeFormat``: The time format * ``pattern``: A date time pattern * ``timezone``: The date timezone * ``calendar``: The calendar ("gregorian" by default) + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/language_name.rst b/doc/filters/language_name.rst index 55c243920..96295950e 100644 --- a/doc/filters/language_name.rst +++ b/doc/filters/language_name.rst @@ -1,8 +1,8 @@ ``language_name`` ================= -The ``language_name`` filter returns the language name given its two-letter -code: +The ``language_name`` filter returns the language name based on its two-letter code (ISO 639-1), +three-letter code (ISO 639-2) or other specific localized code: .. code-block:: twig @@ -44,4 +44,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/filters/locale_name.rst b/doc/filters/locale_name.rst index c6d34cbc0..dd835055c 100644 --- a/doc/filters/locale_name.rst +++ b/doc/filters/locale_name.rst @@ -1,8 +1,7 @@ ``locale_name`` =============== -The ``locale_name`` filter returns the locale name given its two-letter -code: +The ``locale_name`` filter returns the locale name given its code: .. code-block:: twig @@ -44,4 +43,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/filters/slug.rst b/doc/filters/slug.rst index 773a42fac..57085f767 100644 --- a/doc/filters/slug.rst +++ b/doc/filters/slug.rst @@ -56,4 +56,7 @@ Arguments --------- * ``separator``: The separator that is used to join words (defaults to ``-``) -* ``locale``: The locale of the original string (if none is specified, it will be automatically detected) +* ``locale``: The locale code of the original string as defined in `RFC 5646`_ (if none is specified, it will be automatically detected). They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file diff --git a/doc/filters/timezone_name.rst b/doc/filters/timezone_name.rst index dfb22818b..1391ffe07 100644 --- a/doc/filters/timezone_name.rst +++ b/doc/filters/timezone_name.rst @@ -1,7 +1,7 @@ ``timezone_name`` ================= -The ``timezone_name`` filter returns the timezone name given a timezone identifier: +The ``timezone_name`` filter returns the timezone name given its ISO 8601 timezone identifier: .. code-block:: twig @@ -43,4 +43,7 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/country_names.rst b/doc/functions/country_names.rst index 692137b04..fe03ba522 100644 --- a/doc/functions/country_names.rst +++ b/doc/functions/country_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/country_timezones.rst b/doc/functions/country_timezones.rst index ecbbc1c99..370a4beff 100644 --- a/doc/functions/country_timezones.rst +++ b/doc/functions/country_timezones.rst @@ -2,13 +2,15 @@ ===================== The ``country_timezones`` function returns the names of the timezones associated -with a given country code: +with a given country its ISO-3166 code: .. code-block:: twig {# Europe/Paris #} {{ country_timezones('FR')|join(', ') }} +If the specified country were to be unknown, it will return an empty array + .. note:: The ``country_timezones`` function is part of the ``IntlExtension`` which is not @@ -30,3 +32,8 @@ with a given country code: $twig = new \Twig\Environment(...); $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``country``: The country code \ No newline at end of file diff --git a/doc/functions/currency_names.rst b/doc/functions/currency_names.rst index dfb446c86..8df215eb2 100644 --- a/doc/functions/currency_names.rst +++ b/doc/functions/currency_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/language_names.rst b/doc/functions/language_names.rst index f1cce488a..dd9b8930f 100644 --- a/doc/functions/language_names.rst +++ b/doc/functions/language_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/locale_names.rst b/doc/functions/locale_names.rst index 320ab6724..3a8b71fe4 100644 --- a/doc/functions/locale_names.rst +++ b/doc/functions/locale_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/script_names.rst b/doc/functions/script_names.rst index 79b20c65f..963526f66 100644 --- a/doc/functions/script_names.rst +++ b/doc/functions/script_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php diff --git a/doc/functions/timezone_names.rst b/doc/functions/timezone_names.rst index 69db196fd..5aa769910 100644 --- a/doc/functions/timezone_names.rst +++ b/doc/functions/timezone_names.rst @@ -44,4 +44,7 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale +* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. + +.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 +.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php From 1d31ac4b77f4c63e2d93aa9aea6af2b486b65de6 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 28 Sep 2024 09:51:56 +0200 Subject: [PATCH 4/6] Tweak previous merge --- doc/filters/country_name.rst | 12 +++--------- doc/filters/currency_name.rst | 8 +++----- doc/filters/currency_symbol.rst | 7 +++---- doc/filters/format_currency.rst | 5 ++--- doc/filters/format_date.rst | 5 ++--- doc/filters/format_datetime.rst | 5 ++--- doc/filters/format_number.rst | 5 ++--- doc/filters/format_time.rst | 5 ++--- doc/filters/language_name.rst | 9 ++++----- doc/filters/locale_name.rst | 5 ++--- doc/filters/slug.rst | 5 ++--- doc/filters/timezone_name.rst | 5 ++--- doc/functions/country_names.rst | 5 ++--- doc/functions/currency_names.rst | 5 ++--- doc/functions/language_names.rst | 5 ++--- doc/functions/locale_names.rst | 5 ++--- doc/functions/script_names.rst | 5 ++--- doc/functions/timezone_names.rst | 5 ++--- 18 files changed, 41 insertions(+), 65 deletions(-) diff --git a/doc/filters/country_name.rst b/doc/filters/country_name.rst index 394e9f5b7..a30184de9 100644 --- a/doc/filters/country_name.rst +++ b/doc/filters/country_name.rst @@ -1,8 +1,7 @@ ``country_name`` ================ -The ``country_name`` filter returns the country name given its ISO-3166 -two-letter code: +The ``country_name`` filter returns the country name given its ISO-3166 code: .. code-block:: twig @@ -16,10 +15,6 @@ By default, the filter uses the current locale. You can pass it explicitly: {# États-Unis #} {{ 'US'|country_name('fr') }} -The locale can contain more than two letters depending on the region: - -.. code-block:: twig - {# 美國 #} {{ 'US'|country_name('zh_Hant_HK') }} @@ -48,7 +43,6 @@ The locale can contain more than two letters depending on the region: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/currency_name.rst b/doc/filters/currency_name.rst index 9c8aba2a2..498dc9423 100644 --- a/doc/filters/currency_name.rst +++ b/doc/filters/currency_name.rst @@ -1,8 +1,7 @@ ``currency_name`` ================= -The ``currency_name`` filter returns the currency name given its ISO 4217 three-letter -code: +The ``currency_name`` filter returns the currency name given its ISO 4217 code: .. code-block:: twig @@ -44,7 +43,6 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/currency_symbol.rst b/doc/filters/currency_symbol.rst index 716a7f310..80843fba0 100644 --- a/doc/filters/currency_symbol.rst +++ b/doc/filters/currency_symbol.rst @@ -1,7 +1,7 @@ ``currency_symbol`` =================== -The ``currency_symbol`` filter returns the currency symbol given its ISO 4217 three-letter +The ``currency_symbol`` filter returns the currency symbol given its ISO 4217 code: .. code-block:: twig @@ -44,7 +44,6 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/format_currency.rst b/doc/filters/format_currency.rst index 702409ee9..6f1036d33 100644 --- a/doc/filters/format_currency.rst +++ b/doc/filters/format_currency.rst @@ -74,7 +74,6 @@ Arguments * ``currency``: The currency * ``attrs``: A map of attributes -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/format_date.rst b/doc/filters/format_date.rst index c36748ecc..ab0d609df 100644 --- a/doc/filters/format_date.rst +++ b/doc/filters/format_date.rst @@ -29,11 +29,10 @@ the :doc:`format_datetime` filter, but without the time. Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ * ``dateFormat``: The date format * ``pattern``: A date time pattern * ``timezone``: The date timezone * ``calendar``: The calendar ("gregorian" by default) -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/format_datetime.rst b/doc/filters/format_datetime.rst index 4420a8f2c..5f3a49b0c 100644 --- a/doc/filters/format_datetime.rst +++ b/doc/filters/format_datetime.rst @@ -98,7 +98,7 @@ The default timezone can also be set globally by calling ``setTimezone()``:: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ * ``dateFormat``: The date format * ``timeFormat``: The time format * ``pattern``: A date time pattern @@ -106,5 +106,4 @@ Arguments * ``calendar``: The calendar ("gregorian" by default) .. _ICU user guide: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/format_number.rst b/doc/filters/format_number.rst index f964d3984..e1bedc2fc 100644 --- a/doc/filters/format_number.rst +++ b/doc/filters/format_number.rst @@ -112,9 +112,8 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ * ``attrs``: A map of attributes * ``style``: The style of the number output -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/format_time.rst b/doc/filters/format_time.rst index 25710e5ce..8709a6bcf 100644 --- a/doc/filters/format_time.rst +++ b/doc/filters/format_time.rst @@ -29,11 +29,10 @@ the :doc:`format_datetime` filter, but without the date. Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ * ``timeFormat``: The time format * ``pattern``: A date time pattern * ``timezone``: The date timezone * ``calendar``: The calendar ("gregorian" by default) -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/language_name.rst b/doc/filters/language_name.rst index 96295950e..ccffd20eb 100644 --- a/doc/filters/language_name.rst +++ b/doc/filters/language_name.rst @@ -1,8 +1,8 @@ ``language_name`` ================= -The ``language_name`` filter returns the language name based on its two-letter code (ISO 639-1), -three-letter code (ISO 639-2) or other specific localized code: +The ``language_name`` filter returns the language name based on its ISO 639-1 +code, ISO 639-2 code, or other specific localized code: .. code-block:: twig @@ -44,7 +44,6 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/locale_name.rst b/doc/filters/locale_name.rst index dd835055c..9e0df0738 100644 --- a/doc/filters/locale_name.rst +++ b/doc/filters/locale_name.rst @@ -43,7 +43,6 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/slug.rst b/doc/filters/slug.rst index 57085f767..f5b91b2da 100644 --- a/doc/filters/slug.rst +++ b/doc/filters/slug.rst @@ -56,7 +56,6 @@ Arguments --------- * ``separator``: The separator that is used to join words (defaults to ``-``) -* ``locale``: The locale code of the original string as defined in `RFC 5646`_ (if none is specified, it will be automatically detected). They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code of the original string as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php \ No newline at end of file +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/filters/timezone_name.rst b/doc/filters/timezone_name.rst index 1391ffe07..26c6f8917 100644 --- a/doc/filters/timezone_name.rst +++ b/doc/filters/timezone_name.rst @@ -43,7 +43,6 @@ By default, the filter uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/country_names.rst b/doc/functions/country_names.rst index fe03ba522..f65b265ed 100644 --- a/doc/functions/country_names.rst +++ b/doc/functions/country_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/currency_names.rst b/doc/functions/currency_names.rst index 8df215eb2..9113aa088 100644 --- a/doc/functions/currency_names.rst +++ b/doc/functions/currency_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/language_names.rst b/doc/functions/language_names.rst index dd9b8930f..145a49557 100644 --- a/doc/functions/language_names.rst +++ b/doc/functions/language_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/locale_names.rst b/doc/functions/locale_names.rst index 3a8b71fe4..b8597f980 100644 --- a/doc/functions/locale_names.rst +++ b/doc/functions/locale_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/script_names.rst b/doc/functions/script_names.rst index 963526f66..cddf9310a 100644 --- a/doc/functions/script_names.rst +++ b/doc/functions/script_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 diff --git a/doc/functions/timezone_names.rst b/doc/functions/timezone_names.rst index 5aa769910..98c5871ea 100644 --- a/doc/functions/timezone_names.rst +++ b/doc/functions/timezone_names.rst @@ -44,7 +44,6 @@ By default, the function uses the current locale. You can pass it explicitly: Arguments --------- -* ``locale``: The locale code as defined in `RFC 5646`_. They are also documented in the `PHP Locale class`_. +* ``locale``: The locale code as defined in `RFC 5646`_ -.. _`RFC 5646`: https://www.rfc-editor.org/info/rfc5646 -.. _`PHP Locale class`: https://www.php.net/manual/en/class.locale.php +.. _RFC 5646: https://www.rfc-editor.org/info/rfc5646 From 1488238e3287eab00bb9351b1803046ae0d95ddc Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 27 Sep 2024 22:51:56 +0200 Subject: [PATCH 5/6] Fix ignored parenthesis in expressions --- CHANGELOG | 1 + src/ExpressionParser.php | 7 ++++++- src/Node/Expression/Unary/AbstractUnary.php | 16 ++++++++++++++-- tests/Fixtures/expressions/power.test | 8 ++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f2311502a..9edf14f51 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ # 3.15.0 (2024-XX-XX) + * Fix `power` expressions with a negative number in parenthesis (`(-1) ** 2`) * Deprecate instantiating `Node` directly. Use `EmptyNode` or `Nodes` instead. * Add support for inline comments * Add support for accessing class constants with the dot operator diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php index cd1b1993e..97e3ae003 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -172,7 +172,12 @@ class ExpressionParser $expr = $this->parseExpression(); $this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed'); - return $this->parsePostfixExpression($expr); + $expr = $this->parsePostfixExpression($expr); + if ($expr instanceof NegUnary) { + $expr->wrapInParentheses(); + } + + return $expr; } return $this->parsePrimaryExpression(); diff --git a/src/Node/Expression/Unary/AbstractUnary.php b/src/Node/Expression/Unary/AbstractUnary.php index e31e3f84b..b9b44ed4f 100644 --- a/src/Node/Expression/Unary/AbstractUnary.php +++ b/src/Node/Expression/Unary/AbstractUnary.php @@ -20,14 +20,26 @@ abstract class AbstractUnary extends AbstractExpression { public function __construct(Node $node, int $lineno) { - parent::__construct(['node' => $node], [], $lineno); + parent::__construct(['node' => $node], ['with_parentheses' => false], $lineno); + } + + public function wrapInParentheses(): void + { + $this->setAttribute('with_parentheses', true); } public function compile(Compiler $compiler): void { - $compiler->raw(' '); + if ($this->getAttribute('with_parentheses')) { + $compiler->raw('('); + } else { + $compiler->raw(' '); + } $this->operator($compiler); $compiler->subcompile($this->getNode('node')); + if ($this->getAttribute('with_parentheses')) { + $compiler->raw(')'); + } } abstract public function operator(Compiler $compiler): Compiler; diff --git a/tests/Fixtures/expressions/power.test b/tests/Fixtures/expressions/power.test index 84fd23692..5fb3fa4b5 100644 --- a/tests/Fixtures/expressions/power.test +++ b/tests/Fixtures/expressions/power.test @@ -8,6 +8,10 @@ Twig parses power expressions {{ a ** b }} {{ b ** a }} {{ b ** b }} +{{ -1**0 }} +{{ (-1)**0 }} +{{ -a**0 }} +{{ (-a)**0 }} --DATA-- return ['a' => 4, 'b' => -2] --EXPECT-- @@ -18,3 +22,7 @@ return ['a' => 4, 'b' => -2] 0.0625 16 0.25 +-1 +1 +-1 +1 From e83c3c888be0d176ff061791bf269ce8e2ffc284 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 29 Sep 2024 17:54:02 +0200 Subject: [PATCH 6/6] Add an additional example in the docs --- doc/templates.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/templates.rst b/doc/templates.rst index b87ee1ed7..6626d4ee8 100644 --- a/doc/templates.rst +++ b/doc/templates.rst @@ -167,21 +167,24 @@ filters. A common mistake is to forget using parentheses for filters on negative numbers as a negative number in Twig is represented by the ``-`` operator followed by a positive number. As the ``-`` operator has a lower precedence - than the filter operator, it leads to confusion: + than the filter operator, it can lead to confusion: .. code-block:: twig {{ -1|abs }} {# returns -1 #} + {{ -1**0 }} {% returns -1 %} {# as it is equivalent to #} {{ -(1|abs) }} + {{ -(1**0) }} For such cases, use parentheses to force the precedence: .. code-block:: twig {{ (-1)|abs }} {# returns 1 as expected #} + {{ (-1)**0 }} {% returns 1 %} Functions ---------