From a8583c8e6901b8014e8ab21aa2c8a098377344f9 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Sat, 9 Dec 2023 17:12:07 +0000 Subject: [PATCH] added backend translation support for plurals --- mealie/pkgs/i18n/json_provider.py | 26 ++++++++++++++++--- .../pkgs/i18n/test_locale_provider.py | 23 ++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/mealie/pkgs/i18n/json_provider.py b/mealie/pkgs/i18n/json_provider.py index 34cc7710c458..5fbeb10c902d 100644 --- a/mealie/pkgs/i18n/json_provider.py +++ b/mealie/pkgs/i18n/json_provider.py @@ -1,6 +1,7 @@ import json from dataclasses import dataclass from pathlib import Path +from typing import cast @dataclass(slots=True) @@ -13,6 +14,22 @@ class JsonProvider: else: self.translations = path + def _parse_plurals(self, value: str, count: float): + # based off of: https://kazupon.github.io/vue-i18n/guide/pluralization.html + + values = [v.strip() for v in value.split("|")] + if len(values) == 1: + return value + elif len(values) == 2: + return values[0] if count == 1 else values[1] + elif len(values) == 3: + if count == 0: + return values[0] + else: + return values[1] if count == 1 else values[2] + else: + return values[0] + def t(self, key: str, default=None, **kwargs) -> str: keys = key.split(".") @@ -30,9 +47,12 @@ class JsonProvider: if i == last: for key, value in kwargs.items(): - if not value: + translation_value = cast(str, translation_value) + if value is None: value = "" - translation_value = translation_value.replace("{" + key + "}", value) - return translation_value + if key == "count": + translation_value = self._parse_plurals(translation_value, float(value)) + translation_value = translation_value.replace("{" + key + "}", str(value)) # type: ignore + return translation_value # type: ignore return default or key diff --git a/tests/unit_tests/pkgs/i18n/test_locale_provider.py b/tests/unit_tests/pkgs/i18n/test_locale_provider.py index 73100fb739a6..f4bf3a550521 100644 --- a/tests/unit_tests/pkgs/i18n/test_locale_provider.py +++ b/tests/unit_tests/pkgs/i18n/test_locale_provider.py @@ -9,6 +9,29 @@ def test_json_provider(): assert provider.t("test2", "DEFAULT") == "DEFAULT" +def test_json_provider_plural(): + provider = JsonProvider({"test": "test | tests"}) + assert provider.t("test", count=0) == "tests" + assert provider.t("test", count=0.5) == "tests" + assert provider.t("test", count=1) == "test" + assert provider.t("test", count=1.5) == "tests" + assert provider.t("test", count=2) == "tests" + + provider = JsonProvider({"test": "test 0 | test | tests"}) + assert provider.t("test", count=0) == "test 0" + assert provider.t("test", count=0.5) == "tests" + assert provider.t("test", count=1) == "test" + assert provider.t("test", count=1.5) == "tests" + assert provider.t("test", count=2) == "tests" + + provider = JsonProvider({"test": "zero tests | one test | {count} tests"}) + assert provider.t("test", count=0) == "zero tests" + assert provider.t("test", count=0.5) == "0.5 tests" + assert provider.t("test", count=1) == "one test" + assert provider.t("test", count=1.5) == "1.5 tests" + assert provider.t("test", count=2) == "2 tests" + + def test_json_provider_nested_keys(): nested_dict = { "root": {