You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An optimized translation, used by default for CSV Translations.
4
+
An optimized translation.
5
5
</brief_description>
6
6
<description>
7
-
An optimized translation, used by default for CSV Translations. Uses real-time compressed translations, which results in very small dictionaries.
7
+
An optimized translation. Uses real-time compressed translations, which results in very small dictionaries.
8
+
This class does not store the untranslated strings for optimization purposes. Therefore, [method Translation.get_message_list] always returns an empty array, and [method Translation.get_message_count] always returns [code]0[/code].
8
9
</description>
9
10
<tutorials>
10
11
</tutorials>
@@ -14,6 +15,7 @@
14
15
<paramindex="0"name="from"type="Translation" />
15
16
<description>
16
17
Generates and sets an optimized translation from the given [Translation] resource.
18
+
[b]Note:[/b] Messages in [param from] should not use context or plural forms.
17
19
[b]Note:[/b] This method is intended to be used in the editor. It does nothing when called from an exported project.
Comma-separated values are a plain text table storage format. The format's simplicity makes it easy to edit in any text editor or spreadsheet software. This makes it a common choice for game localization.
8
+
In the CSV file used for translation, the first column contains string identifiers, and the first row serves as the header. The first column's header can be any value. The remaining headers indicate the locale for that column. Columns whose headers begin with an underscore ([code]_[/code]) will be ignored.
8
9
[b]Example CSV file:[/b]
9
10
[codeblock lang=text]
10
11
keys,en,es,ja
@@ -13,16 +14,38 @@
13
14
BYE,Goodbye,Adiós,さようなら
14
15
QUOTE,"""Hello"" said the man.","""Hola"" dijo el hombre.",「こんにちは」男は言いました
15
16
[/codeblock]
17
+
Although keys in the first column typically use uppercase string identifiers, it is not uncommon to directly use strings appearing in the game as keys. To avoid string ambiguity, you can use a special [code]?context[/code] column to specify the context to use with [method Object.tr].
18
+
[codeblock lang=text]
19
+
en,?context,fr,ja,zh
20
+
Letter,Alphabet,Lettre,字母,字母
21
+
Letter,Message,Courrier,手紙,信件
22
+
[/codeblock]
23
+
To set the plural form of a string to use with [method Object.tr_n], add a special [code]?plural[/code] column. After setting the plural form of the source string in this column, you can add additional rows to provide translations for more plural forms. The first column and all special columns in these plural form rows must be empty.
24
+
Godot includes built-in plural rules for some languages. You can also customize them using a special [code]?pluralrule[/code] row. See [url=https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html]GNU gettext[/url] for examples and more info.
25
+
[codeblock lang=text]
26
+
en,?plural,fr,ru,zh,_Comment
27
+
?pluralrule,,nplurals=2; plural=(n >= 2);,,,Customize the plural rule for French
28
+
There is %d apple,There are %d apples,Il y a %d pomme,Есть %d яблоко,那里有%d个苹果,
If [code]true[/code], creates an [OptimizedTranslation] instead of a [Translation]. This makes the resulting file smaller at the cost of a small CPU overhead.
- [b]Auto[/b]: Creates an [OptimizedTranslation] when possible. This makes the resulting file smaller at the cost of a small CPU overhead. Falls back to [Translation] for translations with context or plural forms.
const Vector<String> line = f->get_csv_line(delimiter);
100
+
for (int i = 1; i < line.size(); i++) {
101
+
if (line[i].left(1) == "_") {
102
+
continue;
103
+
}
104
+
if (line[i].to_lower() == "?context") {
105
+
ERR_CONTINUE_MSG(context_column != -1, "Error importing CSV translation: Multiple '?context' columns found. Only one is allowed. Subsequent ones will be ignored.");
106
+
context_column = i;
107
+
continue;
108
+
}
109
+
if (line[i].to_lower() == "?plural") {
110
+
ERR_CONTINUE_MSG(plural_column != -1, "Error importing CSV translation: Multiple '?plural' columns found. Only one is allowed. Subsequent ones will be ignored.");
ERR_CONTINUE_MSG(locale.is_empty(), vformat("Error importing CSV translation: Invalid locale format '%s', should be 'language_Script_COUNTRY_VARIANT@extra'. This column will be ignored.", line[i]));
103
117
104
-
if (line[i].left(1) == "_") {
105
-
skipped_locales.insert(i);
106
-
continue;
107
-
} elseif (locale.is_empty()) {
108
-
skipped_locales.insert(i);
109
-
ERR_CONTINUE_MSG(true, vformat("Error importing CSV translation: Invalid locale format '%s', should be 'language_Script_COUNTRY_VARIANT@extra'. This column will be ignored.", line[i]));
118
+
Ref<Translation> translation;
119
+
translation.instantiate();
120
+
translation->set_locale(locale);
121
+
column_to_translation[i] = translation;
110
122
}
111
123
112
-
locales.push_back(locale);
113
-
Ref<Translation> translation;
114
-
translation.instantiate();
115
-
translation->set_locale(locale);
116
-
translations.push_back(translation);
124
+
ERR_FAIL_COND_V_MSG(column_to_translation.is_empty(), ERR_PARSE_ERROR, "Error importing CSV translation: The CSV file must have at least one column for key and one column for translation.");
117
125
}
118
126
119
-
do {
120
-
line = f->get_csv_line(delimiter);
121
-
String key = line[0];
122
-
if (!key.is_empty()) {
123
-
ERR_CONTINUE_MSG(line.size() != locales.size() + (int)skipped_locales.size() + 1, vformat("Error importing CSV translation: expected %d locale(s), but the '%s' key has %d locale(s).", locales.size(), key, line.size() - 1));
ERR_CONTINUE_MSG(!translation->get_plural_rules_override().is_empty(), vformat("Error importing CSV translation: Multiple '?pluralrule' definitions found for locale '%s'. Only one is allowed. Subsequent ones will be ignored.", translation->get_locale()));
0 commit comments