Skip to content

Commit 92f4c71

Browse files
authored
Blocks i18n (#266)
* Add mrc_get_python_variable i18n * Change to use Blockly.Msg * Add i18n for user visible strings * Add i18n support * Add i18n support * Go away from %1 %2
1 parent e31862e commit 92f4c71

File tree

8 files changed

+113
-23
lines changed

8 files changed

+113
-23
lines changed

src/blocks/mrc_get_python_enum_value.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown';
3030
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
3131
import { MRC_STYLE_ENUM } from '../themes/styles'
3232
import * as toolboxItems from '../toolbox/items';
33+
import { replaceTokens } from './tokens';
3334

3435

3536
// A block to access a python enum.
@@ -75,7 +76,10 @@ const GET_PYTHON_ENUM_VALUE = {
7576
this.setTooltip(() => {
7677
const enumClassName = this.getFieldValue(FIELD_ENUM_CLASS_NAME);
7778
const enumValue = this.getFieldValue(FIELD_ENUM_VALUE);
78-
let tooltip = 'Gets the enum value ' + enumClassName + '.' + enumValue + '.';
79+
let tooltip = replaceTokens(Blockly.Msg['GET_ENUM_VALUE_TOOLTIP'], {
80+
enumName: enumClassName,
81+
valueName: enumValue
82+
});
7983
const enumTooltip = PythonEnumTooltips[enumClassName]
8084
if (enumTooltip) {
8185
if (typeof enumTooltip === 'string') {

src/blocks/mrc_get_python_variable.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown';
3434
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
3535
import { MRC_STYLE_VARIABLES } from '../themes/styles';
3636
import * as toolboxItems from '../toolbox/items';
37+
import { replaceTokens } from './tokens';
3738

3839

3940
// A block to get a python variable.
@@ -132,7 +133,7 @@ const GET_PYTHON_VARIABLE = {
132133
*/
133134
init: function(this: GetPythonVariableBlock): void {
134135
this.appendDummyInput('VAR')
135-
.appendField('get')
136+
.appendField(Blockly.Msg['GET'])
136137
.appendField(createFieldNonEditableText(''), FIELD_MODULE_OR_CLASS_NAME)
137138
.appendField('.');
138139
this.setStyle(MRC_STYLE_VARIABLES);
@@ -142,21 +143,30 @@ const GET_PYTHON_VARIABLE = {
142143
switch (this.mrcVarKind) {
143144
case VariableKind.MODULE: {
144145
const moduleName = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
145-
tooltip = 'Gets the variable ' + moduleName + '.' + varName + '.';
146+
tooltip = replaceTokens(Blockly.Msg['GET_MODULE_VARIABLE_TOOLTIP'], {
147+
moduleName: moduleName,
148+
varName: varName
149+
});
146150
break;
147151
}
148152
case VariableKind.CLASS: {
149153
const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
150-
tooltip = 'Gets the variable ' + className + '.' + varName + '.';
154+
tooltip = replaceTokens(Blockly.Msg['GET_CLASS_VARIABLE_TOOLTIP'], {
155+
className: className,
156+
varName: varName
157+
});
151158
break;
152159
}
153160
case VariableKind.INSTANCE: {
154161
const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
155-
tooltip = 'Gets the variable ' + varName + ' for the given ' + className + ' object.';
162+
tooltip = replaceTokens(Blockly.Msg['GET_INSTANCE_VARIABLE_TOOLTIP'], {
163+
varName: varName,
164+
className: className
165+
});
156166
break;
157167
}
158168
default:
159-
throw new Error('mrcVarKind must be "module", "class", or "instance".')
169+
throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']);
160170
}
161171
const varTooltips = PythonVariableGetterTooltips[this.mrcKey];
162172
if (varTooltips) {
@@ -286,7 +296,7 @@ export const pythonFromBlock = function(
286296
return [code, Order.MEMBER];
287297
}
288298
default:
289-
throw new Error('mrcVarKind must be "module", "class", or "instance".')
299+
throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']);
290300
}
291301
};
292302

src/blocks/mrc_mechanism.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const MECHANISM = {
7474
nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField));
7575
this.appendDummyInput()
7676
.appendField(nameField, FIELD_NAME)
77-
.appendField(Blockly.Msg.OF_TYPE)
77+
.appendField(Blockly.Msg['OF_TYPE'])
7878
.appendField(createFieldNonEditableText(''), FIELD_TYPE);
7979
this.setPreviousStatement(true, OUTPUT_NAME);
8080
this.setNextStatement(true, OUTPUT_NAME);
@@ -240,7 +240,7 @@ const MECHANISM = {
240240
this.updateBlock_();
241241
} else {
242242
// Did not find the mechanism.
243-
warnings.push('This block refers to a mechanism that no longer exists.');
243+
warnings.push(Blockly.Msg['MECHANISM_NOT_FOUND_WARNING']);
244244
}
245245
}
246246

src/blocks/mrc_set_python_variable.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { createFieldDropdown } from '../fields/FieldDropdown';
3131
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
3232
import { MRC_STYLE_VARIABLES } from '../themes/styles';
3333
import * as toolboxItems from '../toolbox/items';
34+
import { replaceTokens } from './tokens';
3435

3536

3637
// A block to set a python variable.
@@ -123,7 +124,7 @@ const SET_PYTHON_VARIABLE = {
123124
*/
124125
init: function(this: SetPythonVariableBlock): void {
125126
this.appendValueInput('VALUE')
126-
.appendField('set')
127+
.appendField(Blockly.Msg['SET'])
127128
.appendField(createFieldNonEditableText(''), FIELD_MODULE_OR_CLASS_NAME)
128129
.appendField('.');
129130
this.setStyle(MRC_STYLE_VARIABLES);
@@ -133,21 +134,30 @@ const SET_PYTHON_VARIABLE = {
133134
switch (this.mrcVarKind) {
134135
case VariableKind.MODULE: {
135136
const moduleName = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
136-
tooltip = 'Sets the variable ' + moduleName + '.' + varName + '.';
137+
tooltip = replaceTokens(Blockly.Msg['SET_MODULE_VARIABLE_TOOLTIP'], {
138+
moduleName: moduleName,
139+
varName: varName
140+
});
137141
break;
138142
}
139143
case VariableKind.CLASS: {
140144
const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
141-
tooltip = 'Sets the variable ' + className + '.' + varName + '.';
145+
tooltip = replaceTokens(Blockly.Msg['SET_CLASS_VARIABLE_TOOLTIP'], {
146+
className: className,
147+
varName: varName
148+
});
142149
break;
143150
}
144151
case VariableKind.INSTANCE: {
145152
const className = this.getFieldValue(FIELD_MODULE_OR_CLASS_NAME);
146-
tooltip = 'Sets the variable ' + varName + ' for the given ' + className + ' object.';
153+
tooltip = replaceTokens(Blockly.Msg['SET_INSTANCE_VARIABLE_TOOLTIP'], {
154+
varName: varName,
155+
className: className
156+
});
147157
break;
148158
}
149159
default:
150-
throw new Error('mrcVarKind must be "module", "class", or "instance".')
160+
throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']);
151161
}
152162
const varTooltips = PythonVariableSetterTooltips[this.mrcKey];
153163
if (varTooltips) {
@@ -226,7 +236,7 @@ const SET_PYTHON_VARIABLE = {
226236
} else {
227237
input.appendField(createFieldNonEditableText(''), FIELD_VARIABLE_NAME);
228238
}
229-
input.appendField('to');
239+
input.appendField(Blockly.Msg['TO']);
230240
if (this.mrcVarType) {
231241
input.setCheck(getAllowedTypesForSetCheck(this.mrcVarType));
232242
}
@@ -279,7 +289,7 @@ export const pythonFromBlock = function(
279289
return code;
280290
}
281291
default:
282-
throw new Error('mrcVarKind must be "module", "class", or "instance".')
292+
throw new Error(Blockly.Msg['VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE']);
283293
}
284294
};
285295

src/blocks/tokens.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg {
7171
ROBOT_LOWER_CASE: t('BLOCKLY.ROBOT_LOWER_CASE'),
7272
CREATE: t('BLOCKLY.CREATE'),
7373
FIRE: t('BLOCKLY.FIRE'),
74+
GET: t('BLOCKLY.GET'),
75+
GET_MODULE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_MODULE_VARIABLE'),
76+
GET_CLASS_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_CLASS_VARIABLE'),
77+
GET_INSTANCE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_INSTANCE_VARIABLE'),
78+
GET_ENUM_VALUE_TOOLTIP: t('BLOCKLY.TOOLTIP.GET_ENUM_VALUE'),
79+
SET: t('BLOCKLY.SET'),
80+
TO: t('BLOCKLY.TO'),
81+
SET_MODULE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_MODULE_VARIABLE'),
82+
SET_CLASS_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_CLASS_VARIABLE'),
83+
SET_INSTANCE_VARIABLE_TOOLTIP: t('BLOCKLY.TOOLTIP.SET_INSTANCE_VARIABLE'),
84+
VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE: t('BLOCKLY.ERROR.VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE'),
85+
MECHANISM_NOT_FOUND_WARNING: t('BLOCKLY.WARNING.MECHANISM_NOT_FOUND'),
7486
WARNING_CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_PRIVATE_COMPONENT'),
7587
WARNING_CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT: t('BLOCKLY.WARNING.CALL_COMPONENT_INSTANCE_METHOD_MISSING_COMPONENT'),
7688
WARNING_CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM: t('BLOCKLY.WARNING.CALL_MECHANISM_COMPONENT_INSTANCE_METHOD_MISSING_MECHANISM'),
@@ -115,4 +127,16 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg {
115127
MORE_OPMODE_METHODS_LABEL: t('BLOCKLY.MORE_OPMODE_METHODS_LABEL'),
116128
COMMENT_DEFAULT_TEXT: t('BLOCKLY.COMMENT_DEFAULT_TEXT'),
117129
}
118-
};
130+
};
131+
132+
/**
133+
* Replaces tokens in a string with values from a dictionary.
134+
* @param template String containing tokens in the format {{token}}
135+
* @param values Dictionary mapping token names to their replacement values
136+
* @return String with all tokens replaced by their corresponding values
137+
*/
138+
export function replaceTokens(template: string, values: Record<string, string>): string {
139+
return template.replace(/\{\{(\w+)\}\}/g, (match, token) => {
140+
return values[token] !== undefined ? values[token] : match;
141+
});
142+
}

src/i18n/locales/en/translation.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
"ROBOT": "robot",
115115
"CREATE": "create",
116116
"FIRE": "fire",
117+
"GET": "get",
118+
"SET": "set",
119+
"TO": "to",
117120
"CUSTOM_EVENTS_LABEL": "Custom Events",
118121
"CUSTOM_METHODS_LABEL": "Custom Methods",
119122
"MORE_ROBOT_METHODS_LABEL": "More Robot Methods",
@@ -139,7 +142,14 @@
139142
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the component named {{componentName}} in the mechanism named {{mechanismName}}.",
140143
"CALL_COMPONENT_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the component named {{componentName}}.",
141144
"CALL_ROBOT_INSTANCE_METHOD": "Calls the robot method {{functionName}}.",
142-
"CALL_MECHANISM_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the mechanism named {{mechanismName}}."
145+
"CALL_MECHANISM_INSTANCE_METHOD": "Calls the instance method {{className}}.{{functionName}} on the mechanism named {{mechanismName}}.",
146+
"GET_MODULE_VARIABLE": "Gets the variable {{moduleName}}.{{varName}}.",
147+
"GET_CLASS_VARIABLE": "Gets the variable {{className}}.{{varName}}.",
148+
"GET_INSTANCE_VARIABLE": "Gets the variable {{varName}} for the given {{className}} object.",
149+
"GET_ENUM_VALUE": "Gets the enum value {{enumName}}.{{valueName}}.",
150+
"SET_MODULE_VARIABLE": "Sets the variable {{moduleName}}.{{varName}}.",
151+
"SET_CLASS_VARIABLE": "Sets the variable {{className}}.{{varName}}.",
152+
"SET_INSTANCE_VARIABLE": "Sets the variable {{varName}} for the given {{className}} object."
143153
},
144154
"CATEGORY":{
145155
"LISTS": "Lists",
@@ -169,7 +179,11 @@
169179
"CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "This block is not allowed to be used inside a mechanism.",
170180
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "This block calls a method that no longer exists in the mechanism.",
171181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "This block calls a method in a mechanism that no longer exists.",
172-
"EVENT_NOT_IN_HOLDER": "This block can only go in the events section of the robot or mechanism."
182+
"EVENT_NOT_IN_HOLDER": "This block can only go in the events section of the robot or mechanism.",
183+
"MECHANISM_NOT_FOUND": "This block refers to a mechanism that no longer exists."
184+
},
185+
"ERROR":{
186+
"VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind must be \"module\", \"class\", or \"instance\"."
173187
}
174188
}
175189
}

src/i18n/locales/es/translation.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
"ROBOT": "robot",
116116
"CREATE": "crear",
117117
"FIRE": "disparar",
118+
"GET": "obtener",
119+
"SET": "establecer",
120+
"TO": "a",
118121
"CUSTOM_EVENTS_LABEL": "Eventos Personalizados",
119122
"CUSTOM_METHODS_LABEL": "Métodos Personalizados",
120123
"MORE_ROBOT_METHODS_LABEL": "Más Métodos del Robot",
@@ -140,7 +143,14 @@
140143
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el componente llamado {{componentName}} en el mecanismo llamado {{mechanismName}}.",
141144
"CALL_COMPONENT_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el componente llamado {{componentName}}.",
142145
"CALL_ROBOT_INSTANCE_METHOD": "Llama al método robot {{functionName}}.",
143-
"CALL_MECHANISM_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el mecanismo llamado {{mechanismName}}."
146+
"CALL_MECHANISM_INSTANCE_METHOD": "Llama al método de instancia {{className}}.{{functionName}} en el mecanismo llamado {{mechanismName}}.",
147+
"GET_MODULE_VARIABLE": "Obtiene la variable {{moduleName}}.{{varName}}.",
148+
"GET_CLASS_VARIABLE": "Obtiene la variable {{className}}.{{varName}}.",
149+
"GET_INSTANCE_VARIABLE": "Obtiene la variable {{varName}} para el objeto {{className}} dado.",
150+
"GET_ENUM_VALUE": "Obtiene el valor de enumeración {{enumName}}.{{valueName}}.",
151+
"SET_MODULE_VARIABLE": "Establece la variable {{moduleName}}.{{varName}}.",
152+
"SET_CLASS_VARIABLE": "Establece la variable {{className}}.{{varName}}.",
153+
"SET_INSTANCE_VARIABLE": "Establece la variable {{varName}} para el objeto {{className}} dado."
144154
},
145155
"CATEGORY": {
146156
"LISTS": "Listas",
@@ -170,7 +180,11 @@
170180
"CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "No se permite utilizar este bloque dentro de un mecanismo.",
171181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "Este bloque llama a un método que ya no existe en el mecanismo.",
172182
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "Este bloque llama a un método en un mecanismo que ya no existe.",
173-
"EVENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de eventos del robot o mecanismo."
183+
"EVENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de eventos del robot o mecanismo.",
184+
"MECHANISM_NOT_FOUND": "Este bloque se refiere a un mecanismo que ya no existe."
185+
},
186+
"ERROR":{
187+
"VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind debe ser \"module\", \"class\" o \"instance\"."
174188
}
175189
}
176190
}

src/i18n/locales/he/translation.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
"ROBOT": "רובוט",
115115
"CREATE": "צור",
116116
"FIRE": "הפעל",
117+
"GET": "קבל",
118+
"SET": "הגדר",
119+
"TO": "ל",
117120
"CUSTOM_EVENTS_LABEL": "אירועים מותאמים אישית",
118121
"CUSTOM_METHODS_LABEL": "מתודות מותאמות אישית",
119122
"MORE_ROBOT_METHODS_LABEL": "מתודות נוספות לרובוט",
@@ -139,7 +142,14 @@
139142
"CALL_MECHANISM_COMPONENT_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} על הרכיב {{componentName}} במנגנון {{mechanismName}}.",
140143
"CALL_COMPONENT_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} על הרכיב {{componentName}}.",
141144
"CALL_ROBOT_INSTANCE_METHOD": "קורא למתודת הרובוט {{functionName}}.",
142-
"CALL_MECHANISM_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} במנגנון {{mechanismName}}."
145+
"CALL_MECHANISM_INSTANCE_METHOD": "קורא למתודה {{className}}.{{functionName}} במנגנון {{mechanismName}}.",
146+
"GET_MODULE_VARIABLE": "מקבל את המשתנה {{moduleName}}.{{varName}}.",
147+
"GET_CLASS_VARIABLE": "מקבל את המשתנה {{className}}.{{varName}}.",
148+
"GET_INSTANCE_VARIABLE": "מקבל את המשתנה {{varName}} עבור אובייקט {{className}} נתון.",
149+
"GET_ENUM_VALUE": "מקבל את ערך ההספירה {{enumName}}.{{valueName}}.",
150+
"SET_MODULE_VARIABLE": "מגדיר את המשתנה {{moduleName}}.{{varName}}.",
151+
"SET_CLASS_VARIABLE": "מגדיר את המשתנה {{className}}.{{varName}}.",
152+
"SET_INSTANCE_VARIABLE": "מגדיר את המשתנה {{varName}} עבור אובייקט {{className}} נתון."
143153
},
144154
"CATEGORY": {
145155
"LISTS": "רשימות",
@@ -169,7 +179,11 @@
169179
"CALL_MECHANISM_INSTANCE_METHOD_INSIDE_MECHANISM": "בלוק זה אינו מורשה לשימוש בתוך מנגנון.",
170180
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "בלוק זה קורא למתודה שכבר לא קיימת במנגנון.",
171181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "בלוק זה קורא למתודה במנגנון שכבר לא קיים.",
172-
"EVENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור האירועים של הרובוט או המנגנון."
182+
"EVENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור האירועים של הרובוט או המנגנון.",
183+
"MECHANISM_NOT_FOUND": "בלוק זה מתייחס למנגנון שכבר לא קיים."
184+
},
185+
"ERROR": {
186+
"VAR_KIND_MUST_BE_MODULE_CLASS_OR_INSTANCE": "mrcVarKind חייב להיות \"module\", \"class\" או \"instance\"."
173187
}
174188
}
175189
}

0 commit comments

Comments
 (0)