mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 04:27:00 +00:00
feature #4107 [String] Add singularize and pluralize filter (welcoMattic, fabpot)
This PR was merged into the 3.x branch. Discussion ---------- [String] Add singularize and pluralize filter This PR follows up this one in Symfony https://github.com/symfony/symfony/pull/57245. It adds 2 new filters `singularize` and `pluralize`. It uses the String component, especially `EnglishInflector` and `FrenchInflector`. Examples: ```php {{ 'person'|pluralize('en') }} // persons {{ 'person'|pluralize('en', false) }} // ['persons', 'people'] {{ 'personne'|pluralize('fr') }} // personnes {{ 'personne'|pluralize('fr', false) }} // ['personnes'] {{ 'persons'|singluarize('en') }} // person {{ 'people'|singluarize('en') }} // person {{ 'persons'|singluarize('en', false) }} // ['person'] {{ 'personnes'|singluarize('fr') }} // personne {{ 'personnes'|singluarize('fr', false) }} // ['personne'] {{ 'persona'|pluralize('it') }} // \InvalidArgumentException('Language "it" is not supported.') {{ 'persone'|singluarize('it') }} // \InvalidArgumentException('Language "it" is not supported.') ``` Commits -------8c969d40Tweak code and docscb392489feat(string-extra): Add singularize and pluralize filter
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# 3.11.0 (2024-XX-XX)
|
||||
|
||||
* Add the `singular` and `plural` filters in `StringExtension`
|
||||
* Deprecate the second argument of `Twig\Node\Expression\CallExpression::compileArguments()`
|
||||
* Deprecate `Twig\ExpressionParser\parseHashExpression()` in favor of
|
||||
`Twig\ExpressionParser::parseMappingExpression()`
|
||||
|
||||
@@ -41,11 +41,13 @@ Filters
|
||||
merge
|
||||
nl2br
|
||||
number_format
|
||||
plural
|
||||
raw
|
||||
reduce
|
||||
replace
|
||||
reverse
|
||||
round
|
||||
singular
|
||||
slice
|
||||
slug
|
||||
sort
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
``plural``
|
||||
==========
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
The ``plural`` filter was added in Twig 3.11.
|
||||
|
||||
The ``plural`` filter transforms a given noun in its singular form into its
|
||||
plural version:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{# English (en) rules are used by default #}
|
||||
{{ 'partition'|pluralize() }}
|
||||
partitions
|
||||
|
||||
{{ 'partition'|pluralize('fr') }}
|
||||
partitions
|
||||
|
||||
.. note::
|
||||
|
||||
The ``plural`` filter is part of the ``StringExtension`` which is not
|
||||
installed by default. Install it first:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ composer require twig/string-extra
|
||||
|
||||
Then, on Symfony projects, install the ``twig/extra-bundle``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ composer require twig/extra-bundle
|
||||
|
||||
Otherwise, add the extension explicitly on the Twig environment::
|
||||
|
||||
use Twig\Extra\String\StringExtension;
|
||||
|
||||
$twig = new \Twig\Environment(...);
|
||||
$twig->addExtension(new StringExtension());
|
||||
|
||||
Arguments
|
||||
---------
|
||||
|
||||
* ``locale``: The locale of the original string (limited to languages supported by the from Symfony `inflector`_, part of the String component)
|
||||
* ``all``: Whether to return all possible plurals as an array, default is ``false``
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, Twig uses the `pluralize`_ method from the Symfony String component.
|
||||
|
||||
.. _`inflector`: <https://symfony.com/doc/current/components/string.html#inflector>
|
||||
.. _`pluralize`: <https://symfony.com/doc/current/components/string.html#inflector>
|
||||
@@ -0,0 +1,52 @@
|
||||
``singular``
|
||||
============
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
The ``singular`` filter was added in Twig 3.11.
|
||||
|
||||
The ``singular`` filter transforms a given noun in its plural form into its
|
||||
singular version:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{# English (en) rules are used by default #}
|
||||
{{ 'partitions'|singular() }}
|
||||
partition
|
||||
|
||||
{{ 'partitions'|singular('fr') }}
|
||||
partition
|
||||
|
||||
.. note::
|
||||
|
||||
The ``singular`` filter is part of the ``StringExtension`` which is not
|
||||
installed by default. Install it first:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ composer require twig/string-extra
|
||||
|
||||
Then, on Symfony projects, install the ``twig/extra-bundle``:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ composer require twig/extra-bundle
|
||||
|
||||
Otherwise, add the extension explicitly on the Twig environment::
|
||||
|
||||
use Twig\Extra\String\StringExtension;
|
||||
|
||||
$twig = new \Twig\Environment(...);
|
||||
$twig->addExtension(new StringExtension());
|
||||
|
||||
Arguments
|
||||
---------
|
||||
|
||||
* ``locale``: The locale of the original string (limited to languages supported by the from Symfony `inflector`_, part of the String component)
|
||||
* ``all``: Whether to return all possible plurals as an array, default is ``false``
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, Twig uses the `singularize`_ method from the Symfony String component.
|
||||
|
||||
.. _`singularize`: <https://symfony.com/doc/current/components/string.html#inflector>
|
||||
@@ -2,15 +2,20 @@ String Extension
|
||||
================
|
||||
|
||||
This package is a Twig extension that provides integration with the Symfony
|
||||
String component.
|
||||
String component. It provides the following filters:
|
||||
|
||||
It provides a [`u`][1] filter that wraps a text in a `UnicodeString`
|
||||
object to give access to [methods of the class][2].
|
||||
* [`u`][1]: Wraps a text in a `UnicodeString` object to give access to
|
||||
[methods of the class][2].
|
||||
|
||||
It also provides a [`slug`][3] filter which is simply a wrapper for the
|
||||
[`AsciiSlugger`][4]'s `slug` method.
|
||||
* [`slug`][3]: Wraps the [`AsciiSlugger`][4]'s `slug` method.
|
||||
|
||||
* [`singular`][5] and [`plural`][6]: Wraps the [`Inflector`][7] `singularize`
|
||||
and `pluralize` methods.
|
||||
|
||||
[1]: https://twig.symfony.com/u
|
||||
[2]: https://symfony.com/doc/current/components/string.html
|
||||
[3]: https://twig.symfony.com/slug
|
||||
[4]: https://symfony.com/doc/current/components/string.html#slugger
|
||||
[5]: https://twig.symfony.com/singular
|
||||
[6]: https://twig.symfony.com/plural
|
||||
[7]: https://symfony.com/doc/current/components/string.html#inflector
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
namespace Twig\Extra\String;
|
||||
|
||||
use Symfony\Component\String\AbstractUnicodeString;
|
||||
use Symfony\Component\String\Inflector\EnglishInflector;
|
||||
use Symfony\Component\String\Inflector\FrenchInflector;
|
||||
use Symfony\Component\String\Inflector\InflectorInterface;
|
||||
use Symfony\Component\String\Slugger\AsciiSlugger;
|
||||
use Symfony\Component\String\Slugger\SluggerInterface;
|
||||
use Symfony\Component\String\UnicodeString;
|
||||
@@ -21,6 +24,8 @@ use Twig\TwigFilter;
|
||||
final class StringExtension extends AbstractExtension
|
||||
{
|
||||
private $slugger;
|
||||
private $frenchInflector;
|
||||
private $englishInflector;
|
||||
|
||||
public function __construct(?SluggerInterface $slugger = null)
|
||||
{
|
||||
@@ -32,6 +37,8 @@ final class StringExtension extends AbstractExtension
|
||||
return [
|
||||
new TwigFilter('u', [$this, 'createUnicodeString']),
|
||||
new TwigFilter('slug', [$this, 'createSlug']),
|
||||
new TwigFilter('plural', [$this, 'plural']),
|
||||
new TwigFilter('singular', [$this, 'singular']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -44,4 +51,40 @@ final class StringExtension extends AbstractExtension
|
||||
{
|
||||
return $this->slugger->slug($string, $separator, $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string
|
||||
*/
|
||||
public function plural(string $value, string $locale = 'en', bool $all = false)
|
||||
{
|
||||
if ($all) {
|
||||
return $this->getInflector($locale)->pluralize($value);
|
||||
}
|
||||
|
||||
return $this->getInflector($locale)->pluralize($value)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|string
|
||||
*/
|
||||
public function singular(string $value, string $locale = 'en', bool $all = false)
|
||||
{
|
||||
if ($all) {
|
||||
return $this->getInflector($locale)->singularize($value);
|
||||
}
|
||||
|
||||
return $this->getInflector($locale)->singularize($value)[0];
|
||||
}
|
||||
|
||||
private function getInflector(string $locale): InflectorInterface
|
||||
{
|
||||
switch ($locale) {
|
||||
case 'fr':
|
||||
return $this->frenchInflector ?? $this->frenchInflector = new FrenchInflector();
|
||||
case 'en':
|
||||
return $this->englishInflector ?? $this->englishInflector = new EnglishInflector();
|
||||
default:
|
||||
throw new \InvalidArgumentException(sprintf('Locale "%s" is not supported.', $locale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
"plural" filter
|
||||
--TEMPLATE--
|
||||
{{ 'partition'|plural('it') }}
|
||||
|
||||
--DATA--
|
||||
return []
|
||||
|
||||
--EXCEPTION--
|
||||
Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template ("Language "it" is not supported.") in "index.twig" at line 2.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
"plural" filter
|
||||
--TEMPLATE--
|
||||
{{ 'partition'|plural('fr') }}
|
||||
{{ 'partition'|plural('fr', all=true)|join(',') }}
|
||||
{{ 'person'|plural('fr') }}
|
||||
{{ 'person'|plural('en', all=true)|join(',') }}
|
||||
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
partitions
|
||||
partitions
|
||||
persons
|
||||
persons,people
|
||||
@@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
"singular" filter
|
||||
--TEMPLATE--
|
||||
{{ 'partitions'|singular('it') }}
|
||||
|
||||
--DATA--
|
||||
return []
|
||||
|
||||
--EXCEPTION--
|
||||
Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template ("Language "it" is not supported.") in "index.twig" at line 2.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
"singular" filter
|
||||
--TEMPLATE--
|
||||
{{ 'partitions'|singular('fr') }}
|
||||
{{ 'partitions'|singular('fr', all=true)|join(',') }}
|
||||
{{ 'persons'|singular('fr') }}
|
||||
{{ 'persons'|singular('en', all=true)|join(',') }}
|
||||
{{ 'people'|singular('en') }}
|
||||
{{ 'people'|singular('en', all=true)|join(',') }}
|
||||
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
partition
|
||||
partition
|
||||
person
|
||||
person
|
||||
person
|
||||
person
|
||||
Reference in New Issue
Block a user