i18next-parser icon indicating copy to clipboard operation
i18next-parser copied to clipboard

Add option to ignore contexts

Open Teajey opened this issue 4 years ago โ€ข 4 comments

๐Ÿš€ Feature Proposal

Add an option e.g. ignoreContext that causes the parser to be agnostic about contexts; neither adding, nor removing them from the locale files.

Motivation

I like the idea of using contexts differently in different locales. I can create a succinct translation in one locale, using contexts and nesting, and then use a completely different strategy in another locale. This is quite useful between languages that are syntactically different.

But i18next-parser treats all locales as if they're uniform.

Example

(Note: using contextSeparator: ">")

In EN, I use these translation keys:

    {
      "in_template": {
        "label": "In Template",
        "label>run_once": "From Template",
        "validation": {
          "not_the_same": "$t(in_template.label) and $t(out_template.label) must not be the same.",
          "required": "$t(in_template.label) is required."
        }
      },
      "out_template": {
        "label": "Out Template",
        "label>run_once": "To Template",
        "validation": {
          "required": "$t(out_template.label) is required."
        }
      }
    }

The keys are all nice and normalized, and the nested translations even use the correct context!

and in JA I use these translation keys:

    {
      "in_template": {
        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆ",
        "validation": {
          "not_the_same": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰็”จใจๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
          "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅ‰็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
        }
      },
      "in_template>run_once": {
        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰",
        "validation": {
          "not_the_same": "ๆ™‚้–“ๅ†…็”จใจๆ™‚้–“ๅค–็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
          "required": "ๅฐฑๆฅญๆ™‚้–“ๅ†…็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
        }
      },
      "out_template": {
        "label": "ๆ™‚้–“ๅค–ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆ",
        "validation": {
          "required": "ๅฐฑๆฅญๆ™‚้–“ๅค–็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
        }
      },
      "out_template>run_once": {
        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ",
        "validation": {
          "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
        }
      }
    }

In JA, the translation strings are less uniform, and it's not really my place to change them, so I put the contexts on different keys, and use a more redundant approach.

Now, if I run i18next-parser I get this diff:

diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index c890d157d..371648723 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -50,7 +50,6 @@
       },
       "in_template": {
         "label": "In Template",
-        "label>run_once": "From Template",
         "validation": {
           "not_the_same": "$t(in_template.label) and $t(out_template.label) must not be the same.",
           "required": "$t(in_template.label) is required."
@@ -65,7 +64,6 @@
       },
       "out_template": {
         "label": "Out Template",
-        "label>run_once": "To Template",
         "validation": {
           "required": "$t(out_template.label) is required."
         }
diff --git a/src/locales/ja/translation.json b/src/locales/ja/translation.json
index 773c8e668..84ddd8b62 100644
--- a/src/locales/ja/translation.json
+++ b/src/locales/ja/translation.json
@@ -55,13 +55,6 @@
           "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅ‰็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
         }
       },
-      "in_template>run_once": {
-        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰",
-        "validation": {
-          "not_the_same": "ๆ™‚้–“ๅ†…็”จใจๆ™‚้–“ๅค–็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
-          "required": "ๅฐฑๆฅญๆ™‚้–“ๅ†…็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
-        }
-      },
@@ -75,12 +68,6 @@
           "required": "ๅฐฑๆฅญๆ™‚้–“ๅค–็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
         }
       },
-      "out_template>run_once": {
-        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ",
-        "validation": {
-          "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
-        }
-      },

The contexts are assumed to be unused, as I'm assigning them dynamically, e.g:

t(`${key}.validation.${error}`, { context: type });

So I could add more comments next to the t() call:

  // t("in_template", { context: "run_once" })
  // t("out_template", { context: "run_once" })
  // t("in_template.label", { context: "run_once" })
  // t("out_template.label", { context: "run_once" })

But then I get this result:

diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index c890d157d..6e580d53b 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -56,6 +56,7 @@
           "required": "$t(in_template.label) is required."
         }
       },
+      "in_template>run_once": "UNTRANSLATED",
+      "out_template>run_once": "UNTRANSLATED",
       "schedule": {
         "label": "Schedule"
       },
diff --git a/src/locales/ja/translation.json b/src/locales/ja/translation.json
index 773c8e668..c516836ef 100644
--- a/src/locales/ja/translation.json
+++ b/src/locales/ja/translation.json
@@ -50,18 +50,13 @@
       },
       "in_template": {
         "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆ",
+        "label>run_once": "UNTRANSLATED",
         "validation": {
           "not_the_same": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰็”จใจๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
           "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅ‰็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
         }
       },
-      "in_template>run_once": {
-        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰",
-        "validation": {
-          "not_the_same": "ๆ™‚้–“ๅ†…็”จใจๆ™‚้–“ๅค–็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
-          "required": "ๅฐฑๆฅญๆ™‚้–“ๅ†…็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
-        }
-      },
+      "in_template>run_once": "UNTRANSLATED",
@@ -71,16 +66,12 @@
       },
       "out_template": {
         "label": "ๆ™‚้–“ๅค–ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆ",
+        "label>run_once": "UNTRANSLATED",
         "validation": {
           "required": "ๅฐฑๆฅญๆ™‚้–“ๅค–็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
         }
       },
-      "out_template>run_once": {
-        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ",
-        "validation": {
-          "required": "ๅฐฑๆฅญๅˆ‡ใ‚Šๆ›ฟใˆๅพŒ็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
-        }
-      },
+      "out_template>run_once": "UNTRANSLATED",
       "schedule": {
         "label": "ใ‚นใ‚ฑใ‚ธใƒฅใƒผใƒซ"
       },

Some unnecessary keys are added, and some other required keys are still removed/overwritten.

This seems like a perfectly legitimate use of i18next's contexts, and I think it could work with i18next-parser if I could just configure it to leave contexts alone.

Perhaps there is already a way that i18next-parser can accommodate for this usage? If so, I haven't been able to find it all day...

Teajey avatar Oct 15 '21 03:10 Teajey

I don't think this is possible atm. I've never got a situation in which the context had to be different per locale. @jamuhl Does it seem to you as a valid use of context or would you recommend a different strategy?

karellm avatar Oct 16 '21 12:10 karellm

I guess context can be different per language...as languages can be very different in usage. In locize we were strict with the first versions - but nowadays you can have different keys / context in different languages (makes the editor a lot more difficult to do things right - but I think it's reality and needed)

jamuhl avatar Oct 16 '21 12:10 jamuhl

@Teajey I'd be open for a PR but I'd like to explore options first. ignoreContext could be a boolean or an hash with locales, and an other key that cover all non-listed locales. Something like :

ignoreContext: {
  en: false,
  jp: true,
  other: true
}

ignoreContext: true would be equivalent in your example to:

ignoreContext: {
  en: true,
  jp: true,
  other: true
}

Would you see value in this?

karellm avatar Oct 17 '21 02:10 karellm

I find that if I were to ignore context in one locale, I would want to ignore context in all locales. Especially if I have a context token in a parent key. What if I ignore context in EN, but not JA (or vice-versa)? I would still end up with undesired keys being inserted or removed from locales like so:


diff --git a/src/locales/ja/translation.json b/src/locales/ja/translation.json
index 773c8e668..c516836ef 100644
--- a/src/locales/ja/translation.json
+++ b/src/locales/ja/translation.json
@@ -50,18 +50,13 @@

       },
-      "in_template>run_once": {
-        "label": "ๅˆ‡ใ‚Šๆ›ฟใˆๅ‰",
-        "validation": {
-          "not_the_same": "ๆ™‚้–“ๅ†…็”จใจๆ™‚้–“ๅค–็”จใงๅŒใ˜ใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใฏ่จญๅฎšใงใใพใ›ใ‚“ใ€‚",
-          "required": "ๅฐฑๆฅญๆ™‚้–“ๅ†…็”จใฎใƒ†ใƒณใƒ—ใƒฌใƒผใƒˆใ‚’้ธๆŠžใ—ใฆใใ ใ•ใ„ใ€‚"
-        }
-      },
+      "in_template>run_once": "UNTRANSLATED",

Teajey avatar Oct 17 '21 04:10 Teajey