Correct way of concatenating two strings that must be translated?
Disclaimer: I am no gettext/translation specialist but want to create the best code for supporting our translators :-) What is the correct Python code snippet to create a new string by concatenating two (or more) strings while ensuring that the final result is translated correctly? Example (may not work): msg_prefix = "Hello" msg_body = "world" msg = _(msg_prefix + msg_body) or msg_prefix = _("Hello") msg_body = _("world") msg = msg_prefix + msg_body or ... ? And even more complicated if I want to insert a formatted variable too...: msg_prefix = _("Welcome {name}".format(name=login_name)) msg_body = _("at {location}".format(name=address)) msg = msg_prefix + msg_body or ... ? I think we should collect some code snippets for these common cases (e.g. in our discussed new repo "dev-tools")
Moin On 2023-08-28 22:28 BiT dev <python@altfeld-im.de> wrote:
What is the correct Python code snippet to create a new string by concatenating two (or more) strings while ensuring that the final result is translated correctly?
You have to keep the call order in mind. When is the translation function _() and when the + or format() called? Also visualize the Weblate front-end and what a translator would see. My ApproachTranslatorsDialog is a (good?) example of how to handle that. The translators on Weblate will see nice strings but in the py code it looks quite ugly.
Example (may not work):
msg_prefix = "Hello" msg_body = "world" msg = _(msg_prefix + msg_body)
The function _() will try to translate "Helloworld". But the main problem here is that the GNU gettext utilities scanning the py-files for translatable strings will never see this string. They don't analyze the flow but just seeing the third line and do not know what "msg_prefix" and "msg_body" is. So they just ignore it and the string to translate will never get into a po-file and on Weblate. In the end the translators will never see and translate that string.
msg_prefix = _("Hello") msg_body = _("world") msg = msg_prefix + msg_body
That is fine.
And even more complicated if I want to insert a formatted variable too...:
msg_prefix = _("Welcome {name}".format(name=login_name)) msg_body = _("at {location}".format(name=address)) msg = msg_prefix + msg_body
The first and second line are technically wrong. The format() is called before _() but it should the other way around. Move the closing bracket. msg_body = _("at {location}").format(name=address) In this case format() will process the translated string (e.g. "in {location}"). Another problem (for translators) with your example is that the translatable string is cut into two pieces. The second one "at {location}" doesn't make sense to translators. It is easier for them have a string like this: "Welcome {name} at {location}" Maybe "name" and "location" could be more specific. "person_name" and "living_address" or something like that. If you want to keep the strings separate and really present a "at {location}" to translators on Weblate you can add screenshoots on Weblate to each string to give more context. Finally I would re-write your example like this: msg = _("Welcome {name} at {location}").format( name=login_name, location=address) or if you want to keep the separation between prefix and body: msg_prefix = _("Welcome {name}").format(name=login_name) msg_body = _("at {location}").format(name=address) msg = f"{msg_prefix} {msg_body}" btw: Keep in mind that f-strings (e.g. f"foo {bar}") don't work well with gettext. So avoid them. Kind Christian
participants (2)
-
BiT dev
-
c.buhtz@posteo.jp