{"id":57,"date":"2024-02-26T16:11:00","date_gmt":"2024-02-26T16:11:00","guid":{"rendered":"https:\/\/rudnil.uber.space\/?p=57"},"modified":"2025-02-26T16:22:16","modified_gmt":"2025-02-26T16:22:16","slug":"how-to-handle-developer-translations","status":"publish","type":"post","link":"https:\/\/blog.nilsrudolph.de\/?p=57","title":{"rendered":"How to handle developer translations?"},"content":{"rendered":"\n<p>I our projects we have a developer translations, that are translation written by the developer, that are late replaces by real translations made by professional translators. The translators use a demo system and periodically push new and updated translations into our repository.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>But in our system test we depend on the translation and we do not want our system test to break because the translators have pushed a new wording. That is why we let our automated system test run with the developer translations.<\/p>\n\n\n\n<p>But how should such a language tag look like for a devloper language? Tags like &#8220;de-DE&#8221; or &#8220;en-US&#8221; are used for the real translations and if we use some non exisiting tags like &#8220;de-DEV&#8221; some tools may break, because that is not a valid language Tag. For example in Java the method Local::forLanguageTag and Locale::toLanguageTag will not works with such tags. See:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">package de.nilsrudolph.blog;\n\nimport org.junit.jupiter.api.Test;\n\nimport java.util.Locale;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\npublic class LanguageTag {\n\n    @Test\n    public void testValidLanguageTag() {\n        String validTag = \"de-DE\";\n        assertEquals(Locale.forLanguageTag(validTag).toLanguageTag(), validTag);\n    }\n\n    @Test \/\/This one will fail\n    public void testInvalidLanguageTag() {\n        String invalidTag = \"de-DEV\";\n        assertEquals(Locale.forLanguageTag(invalidTag).toLanguageTag(), invalidTag);\n    }\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p>Out solution is to use a private extension. A private extension begins with the string &#8220;-x&#8221;. So that a tag for a developer language may look like &#8220;de-DE-x-dev&#8221; or &#8220;en-US-x-dev&#8221;<\/p>\n\n\n\n<p>These tags then will work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">package de.nilsrudolph.blog;\n\nimport org.junit.jupiter.api.Test;\n\nimport java.util.Locale;\n\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\npublic class LanguageTag {\n\n    @Test\n    public void testValidLanguageTagWithPrivateExtension() {\n        String validTag = \"de-DE-x-dev\";\n        assertEquals(Locale.forLanguageTag(validTag).toLanguageTag(), validTag);\n    }\n}\n<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I our projects we have a developer translations, that are translation written by the developer, that are late replaces by real translations made by professional translators. The translators use a demo system and periodically push new and updated translations into our repository. But in our system test we depend on the translation and we do [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-57","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/posts\/57","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=57"}],"version-history":[{"count":1,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/posts\/57\/revisions"}],"predecessor-version":[{"id":58,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=\/wp\/v2\/posts\/57\/revisions\/58"}],"wp:attachment":[{"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=57"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=57"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.nilsrudolph.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=57"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}