Appending TranslationStrings to each other
I programmatically build up TranslationStrings based on what the content of the message should be. (A common pattern when building up for example an error message based on several conditions to be displayed somewhere like a flash message in Pyramid.) Something like
message = _('phrase1', mapping={....})
if a:
message += _('phrase2 $b')
else:
message += _('phrase3 $b')
if b:
message += _('phrase4', mapping={....})
return message # Be able to apply a mapping to the appended TranslationString, to map $b above
This doesn't work when I pass it to Pyramid code for translation because by the time I've appended the TranslationStrings to each other it's already a string before it reaches Pyramid. If TranslationStrings are appended to each other it would be good if they would be retained as some kind of compound TranslationString where running the translate function on it would allow each of the sub-TranslationStrings to translate themselves from the .mo files. And to be able to apply a mapping to the compound TranslationString (the last line above) or to each TranslationString that makes it up.
The only alternatives I see to this solution are messy. Either I return several message parts to Pyramid, like return (message1, message2, message3, message4, ...). Or each condition above has the full message, like below, which would lead to repetitive code and also duplication of effort by translators.
if a:
message = _('phrase1 phrase2 phrase4')
Why not leave off the _() bits in the middle, and just apply it at the end, e.g.:
message = 'phrase1'
mapping = {'b': 'Bar'}
if a:
message += 'phrase2 $b')
else:
message += 'phrase3 $b')
if b:
message += 'phrase4'
return _(message, mapping=mapping)
I tried it this way but then it prevents the .pot file generators (like lingua's pot-create) from including the strings in the created file.
In my experience, making any assumptions about the structure of a sentence or phrase across languages is incorrect. Each phrase, in its entirety, needs to be translated independently, thus this type of concatenation should be avoided and you should just interpolate the $b independently for each phrase.
Each phrase should be translated independently. But without concatenation, the only way to pass the TranslationString somewhere (e.g. template or flash message) would be to translate the components of the message individually, concatenate the resulting strings, then pass the result on. Like this:
ts1 = _('message1')
string1 = request.localizer.translate(ts1)
ts2 = _('message2')
string2 = request.localizer.translate(ts2)
ts3 = _('message3')
string3 = request.localizer.translate(ts3)
result = string1 + string2 + string3
But if your templates or flash messages can automatically translate a TranslationString (which is quite easy to set up in Pyramid), it would be much cleaner to do (where TranslationString's + operator is overloaded) the following, and allow a BeforeRender event or flash message function to take care of the conversion.
ts1 = _('message1')
ts2 = _('message2')
ts3 = _('message3')
result = ts1 + ts2 + ts3
After all, if you were returning a 'regular' TranslationString instead of a compound one, you would likely just do this:
ts1 = _('message1')
result = ts1
Having some sort of compound TranslationString would allow application Pyramid views to not worry about translating strings themselves, and treat 'regular' and compound TranslationStrings the same way.
Because the way I handle this now is return either 1 TranslationString, or a list of TranslationStrings. In my BeforeRender event or flash message producer, I test for whether it's been passed an instance of TranslationString or list, and have to handle those 2 cases separately to result in a single translated string. It would be nice to treat them all the same way.
I see. I agree it would be nice if they could be appended in the way you're describing.
This could perhaps be an alternative to https://github.com/Pylons/translationstring/issues/10 about nested translations, for when a TranslationString's mapping contains another TranslationString. Where instead of nesting them you could append them.