Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appending TranslationStrings to each other #17

Open
rightaway opened this issue Jan 13, 2015 · 6 comments
Open

Appending TranslationStrings to each other #17

rightaway opened this issue Jan 13, 2015 · 6 comments

Comments

@rightaway
Copy link

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')
@tseaver
Copy link
Member

tseaver commented Jan 13, 2015

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)

@rightaway
Copy link
Author

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.

@mmerickel
Copy link
Member

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.

@rightaway
Copy link
Author

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.

@mmerickel
Copy link
Member

I see. I agree it would be nice if they could be appended in the way you're describing.

@rightaway
Copy link
Author

This could perhaps be an alternative to #10 about nested translations, for when a TranslationString's mapping contains another TranslationString. Where instead of nesting them you could append them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants