Skip to content

Commit 1e94e46

Browse files
authored
Merge pull request #295 from endlessm/blockdef-translations
Translation infrastructure
2 parents 7834706 + 6d149f0 commit 1e94e46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+33721
-11
lines changed

addons/block_code/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,70 @@ Lean into animations! Godot's animations functionality goes beyond just simple a
6666

6767
Please share feedback in the [Godot Forum Block Coding thread](https://forum.godotengine.org/t/block-coding-high-level-block-based-visual-programming/68941).
6868

69+
## Localization
70+
71+
The plugin supports translations through Godot's [gettext][godot-gettext]
72+
support. We welcome contributions to make the plugin work better in your
73+
language! However, please note that translations in the Godot editor **will
74+
only work with Godot 4.4 or newer**.
75+
76+
The gettext PO files are located in the `addons/block_code/locale` directory.
77+
See the Godot [documentation][godot-gettext] for instructions on working with
78+
PO files.
79+
80+
[godot-gettext]: https://docs.godotengine.org/en/stable/tutorials/i18n/localization_using_gettext.html
81+
82+
For developers, a few things need to be done to keep the translatable strings
83+
up to date.
84+
85+
* If files are added or removed, the list of translatable files needs to be
86+
updated. This can be done by using the **Add** dialog in the [POT
87+
Generation][pot-generation] tab. Or you can use the **Project → Tools →
88+
Update BlockCode translated files** menu item in the editor.
89+
90+
* If translatable strings have changed, the POT file needs to be updated. This
91+
can be done by using the **Generate POT** dialog in the [POT
92+
Generation][pot-generation] tab. Or you can use the **Project → Tools →
93+
Regenerate BlockCode POT file** menu item in the editor.
94+
95+
* If the POT file has changed, the PO message files need to be updated. This
96+
can be done using the gettext `msgmerge` tool in the
97+
`addons/block_code/locale` directory:
98+
```
99+
for po in *.po; do
100+
msgmerge --update --backup=none "$po" godot_block_coding.pot
101+
done
102+
```
103+
104+
[pot-generation]: https://docs.godotengine.org/en/stable/tutorials/i18n/localization_using_gettext.html#automatic-generation-using-the-editor
105+
106+
Strings added in scene files or block definition resources will usually be
107+
extracted for localization and translated in the editor automatically. Strings
108+
in scripts need more consideration.
109+
110+
* `Object`s or `Node`s that are not descendents of the Block Coding panel need
111+
to have their translation domain set with the `set_block_translation_domain`
112+
helper function. This should usually be done in the object's `_init` method
113+
to make sure the translation domain is set before that object or any of its
114+
descendents (which inherit the translation domain by default) try to use
115+
localized strings.
116+
117+
* Usually [`tr`][object-tr] and [`tr_n`][object-tr-n] (or [`atr`][node-atr] and
118+
[`atr_n`][node-atr-n] for `Node`s) should be used to mark translatable
119+
strings. These will eventually call the domain's
120+
[`translate`][domain-translate] or
121+
[`translate_plural`][domain-translate-plural] methods, but the `tr` methods
122+
respect translation settings on the object instances. The only time the
123+
`translate` methods should be called directly is within a static context when
124+
an object instance isn't available.
125+
126+
[object-tr]: https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-tr
127+
[object-tr-n]: https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-tr-n
128+
[node-atr]: https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-atr
129+
[node-atr-n]: https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-atr-n
130+
[domain-translate]: https://docs.godotengine.org/en/latest/classes/class_translationdomain.html#class-translationdomain-method-translate
131+
[domain-translate-plural]: https://docs.godotengine.org/en/latest/classes/class_translationdomain.html#class-translationdomain-method-translate-plural
132+
69133
## Development
70134

71135
### pre-commit

addons/block_code/block_code_node/block_code.gd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33
class_name BlockCode
44
extends Node
55

6+
const TxUtils := preload("res://addons/block_code/translation/utils.gd")
7+
68
@export var block_script: BlockScriptSerialization = null
79

810

11+
func _init():
12+
TxUtils.set_block_translation_domain(self)
13+
14+
915
func _ready():
1016
if Engine.is_editor_hint():
1117
return

addons/block_code/block_code_plugin.gd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ extends EditorPlugin
44
const MainPanelScene := preload("res://addons/block_code/ui/main_panel.tscn")
55
const MainPanel = preload("res://addons/block_code/ui/main_panel.gd")
66
const Types = preload("res://addons/block_code/types/types.gd")
7+
const TxUtils := preload("res://addons/block_code/translation/utils.gd")
78
const ScriptWindow := preload("res://addons/block_code/ui/script_window/script_window.tscn")
89

910
static var main_panel: MainPanel
@@ -12,6 +13,9 @@ static var block_code_button: Button
1213
const BlockInspectorPlugin := preload("res://addons/block_code/inspector_plugin/block_script_inspector.gd")
1314
var block_inspector_plugin: BlockInspectorPlugin
1415

16+
const BlockTranslationParserPlugin := preload("res://addons/block_code/translation/parser.gd")
17+
var _tx_parser_plugin: BlockTranslationParserPlugin
18+
1519
var editor_inspector: EditorInspector
1620

1721
var _selected_block_code: BlockCode
@@ -29,6 +33,11 @@ const DISABLED_CLASSES := [
2933
]
3034

3135

36+
func _init():
37+
TxUtils.load_translations()
38+
TxUtils.set_block_translation_domain(self)
39+
40+
3241
func _enter_tree():
3342
Types.init_cast_graph()
3443

@@ -41,6 +50,14 @@ func _enter_tree():
4150
block_inspector_plugin = BlockInspectorPlugin.new()
4251
add_inspector_plugin(block_inspector_plugin)
4352

53+
if not _tx_parser_plugin:
54+
_tx_parser_plugin = BlockTranslationParserPlugin.new()
55+
add_translation_parser_plugin(_tx_parser_plugin)
56+
57+
# Custom Project->Tools menu items.
58+
add_tool_menu_item(tr("Regenerate %s POT file") % "BlockCode", TxUtils.regenerate_pot_file)
59+
add_tool_menu_item(tr("Update %s translated files") % "BlockCode", TxUtils.update_pot_files)
60+
4461
# Remove unwanted class nodes from create node
4562
old_feature_profile = EditorInterface.get_current_feature_profile()
4663

@@ -69,6 +86,7 @@ func script_window_requested(script: String):
6986

7087

7188
func _exit_tree():
89+
remove_translation_parser_plugin(_tx_parser_plugin)
7290
remove_inspector_plugin(block_inspector_plugin)
7391

7492
if block_code_button:

addons/block_code/inspector_plugin/block_script_inspector.gd

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
extends EditorInspectorPlugin
22

33
const BlockCodePlugin = preload("res://addons/block_code/block_code_plugin.gd")
4+
const TxUtils := preload("res://addons/block_code/translation/utils.gd")
5+
6+
7+
func _init():
8+
TxUtils.set_block_translation_domain(self)
49

510

611
func _can_handle(object):
@@ -11,7 +16,7 @@ func _parse_begin(object):
1116
var block_code := object as BlockCode
1217

1318
var button := Button.new()
14-
button.text = "Open Block Script"
19+
button.text = tr("Open Block Script")
1520
button.pressed.connect(func(): BlockCodePlugin.main_panel.switch_block_code_node(block_code))
1621

1722
var container := MarginContainer.new()

0 commit comments

Comments
 (0)