Open dbnicholson opened 13 hours ago
I would suggest the API not be strictly tied to POT generation, since it could be thinkable to allow generating other translation files in the future (e.g. for fluent I had to re-implement the system, and it is not integrated into the editor UI at all).
Something like UI changes can always have breaking changes. But once an API is public, you can't easily change it until Godot 5.0 release! So it must be carefully considered and thought through.
Cleanest implementation I can think of would be a EditorTranslationGenerator
class which would be implemented for PO by default, and can be implemented by extensions to register custom generators. Draft:
class EditorTranslationGenerator:
# PUBLIC API:
# returns the contents of the generated translation file (e.g. contents of the .pot file) for the specified files
static func generate(input_files: PackedStringArray) -> String
# list of files that are part of the project settings -> pot generation dialog
static func get_files() -> PackedStringArray
# VIRTUAL METHODS:
# used by the UI so it knows which file extension the user can save the file as.
func _get_supported_extensions() -> PackedStringArray
# given all translation ids, returns the contents of the generated translation file (e.g. contents of the .pot file)
# this is basically a virtual version of POTGenerator::_write_to_pot
func _generate(msgids: Array[String], msgids_context_plural: Array[Array]) -> String
class EditorPlugin:
func add_translation_generator(generator: EditorTranslationGenerator) -> void
func remove_translation_generator(generator: EditorTranslationGenerator) -> void
Usage:
var result = EditorTranslationGenerator.generate(EditorTranslationGenerator.get_files())
var f = FileAccess.open("res://my_file.pot", FileAccess.WRITE)
f.store_string(result)
It does seem like a bigger project than just exposing the POTGenerator, but I hope you understand my perspective as well.
Shouldn't we add a --generate-pot
CLI argument instead? Most automation use cases involve using the command line, without requiring a dedicated GDScript to be written for this.
You can generate POT with this code:
@tool
extends EditorScript
func _run() -> void:
var localization = EditorInterface.get_base_control().find_child("*Localization*", true, false)
var file_dialog: EditorFileDialog = localization.get_child(5)
file_dialog.file_selected.emit("res://POT File.pot")
Describe the project you are working on
A plugin with strings to translate.
Describe the problem or limitation you are having in your project
Currently the only way to regenerate POT files is via the localization editor's POT Generation tab. This is the only part of the gettext localization pipeline that can't be automated.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
If
POTGenerator::generate_pot
were exposed to GDScript, you could easily write a script that callsgenerate_pot
with your desired POT file location. This would fill the hole where you'd normally usexgettext
. After that, the rest of the gettext flow works as normal.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Presuming that the
POTGenerator
singleton and itsgenerate_pot
method were available, you could write a simpleSceneTree
script like:Then you could run it like
godot --path . --headless --script genpot.gd
as part of your translation pipeline.If this enhancement will not be used often, can it be worked around with a few lines of script?
I don't believe there's any way to manage this from a script since none of the necessary functionality is exposed to GDScript. Without the enhancement, you'd have to use the POT Generation tab in the editor whenever translatable strings change.
Is there a reason why this should be core and not an add-on in the asset library?
Until the core exposes
POTGenerator
, there's no way to provide this functionality from an add-on.