You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony框架中单个翻译字符串实现多transchoice的替代方案问询

Great question! Let's walk through some alternative approaches to handle multiple plural translations in a single string without overriding Symfony's core Translator component:


1. Split into Separate Translation Keys (Most Straightforward)

The simplest approach is to break each fruit's plural rule into its own dedicated translation key, then combine them in Twig using a template string. This keeps your translation files clean and follows Symfony's standard patterns.

YAML Translation File:

# translations/messages.en.yaml
fruit.banana.plural: '{0}No bananas|{1}One banana|]1.Inf[%count% bananas'
fruit.orange.plural: '{0}No oranges|{1}One orange|]1.Inf[%count% oranges'
fruit.grape.plural: '{0}No grapes|{1}One kilogram of grapes|]1.Inf[%count% kilograms of grapes'
fruit.apple.plural: '{0}No apples|{1}One apple|]1.Inf[%count% apples'
fruit.combined.list: '%bananas%, %oranges%, %grapes% and %apples%.'

Twig Template Call:

{{ 'fruit.combined.list'|trans({
    '%bananas%': 'fruit.banana.plural'|transchoice(4),
    '%oranges%': 'fruit.orange.plural'|transchoice(6),
    '%grapes%': 'fruit.grape.plural'|transchoice(2),
    '%apples%': 'fruit.apple.plural'|transchoice(3)
}) }}

Pros: No custom code required, highly maintainable, easy to update individual fruit translations.
Cons: Requires a bit more Twig code if you have many fruit types, but remains readable.


2. Use ICU Message Format (Symfony 4.2+)

Symfony supports the ICU Message Format natively (enabled by default in newer versions), which is a standardized way to handle complex pluralization, gender, and multiple variables in translations. This is the most robust "out-of-the-box" solution.

YAML Translation File:

# translations/messages.en.yaml
fruit.combined.plural: '{bananas, plural,
    zero {No bananas}
    one {One banana}
    other {# bananas}
}, {oranges, plural,
    zero {No oranges}
    one {One orange}
    other {# oranges}
}, {grapes, plural,
    zero {No grapes}
    one {One kilogram of grapes}
    other {# kilograms of grapes}
} and {apples, plural,
    zero {No apples}
    one {One apple}
    other {# apples}
}.'

Twig Template Call:

{{ 'fruit.combined.plural'|trans({
    'bananas': 4,
    'oranges': 6,
    'grapes': 2,
    'apples': 3
}) }}

Pros: Industry-standard format, supports complex plural rules for different languages, no custom code needed.
Cons: Requires learning the ICU syntax, but it's widely documented and worth investing in for larger projects.


3. Create a Custom Twig Filter (Lightweight Extension)

Instead of overriding the entire Translator, build a custom Twig filter that handles multiple pluralization rules in one call. This is a middle ground between core functionality and full Translator customization.

Step 1: Define the Translation String
Use a clear separator (like ||) to split the base template from individual plural rules in your YAML:

# translations/messages.en.yaml
fruit.multi.plural: '%0%, %1%, %2% and %3%. || {0}No bananas|{1}One banana|]1.Inf[%count% bananas || {0}No oranges|{1}One orange|]1.Inf[%count% oranges || {0}No grapes|{1}One kilogram of grapes|]1.Inf[%count% kilograms of grapes || {0}No apples|{1}One apple|]1.Inf[%count% apples'

Step 2: Build the Custom Filter
Create a Twig extension that splits the translation string, processes each plural rule with transchoice, then replaces the placeholders:

// src/Twig/MultiTranschoiceExtension.php
namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Symfony\Contracts\Translation\TranslatorInterface;

class MultiTranschoiceExtension extends AbstractExtension
{
    public function __construct(private TranslatorInterface $translator) {}

    public function getFilters(): array
    {
        return [
            new TwigFilter('multi_transchoice', [$this, 'multiTranschoice']),
        ];
    }

    public function multiTranschoice(string $translationKey, array $counts): string
    {
        $fullString = $this->translator->trans($translationKey);
        [$template, ...$pluralRules] = explode('||', $fullString);

        foreach ($counts as $index => $count) {
            $pluralized = $this->translator->transchoice(trim($pluralRules[$index]), $count);
            $template = str_replace("%$index%", $pluralized, $template);
        }

        return trim($template);
    }
}

Step 3: Use the Filter in Twig

{{ 'fruit.multi.plural'|multi_transchoice([4,6,2,3]) }}

Pros: Lightweight, doesn't modify core Symfony services, keeps your translation strings grouped.
Cons: Requires writing and maintaining a small extension, but logic is simple.


Final Thoughts

Your current approach of overriding the Translator works, but the ICU Message Format is the most scalable and future-proof option if you're on a supported Symfony version. Splitting into separate keys is the easiest for small projects, while the custom filter is great if you want to keep translations grouped without core overrides.

内容的提问来源于stack exchange,提问作者Craig Rayner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:32:19