4

I am working on a django application, which need to support multiple languages. This application involves some amount of javascript code. In this javascript code, there are some multi-line strings, which need to be translated.

We have tried this structure:

var $text = gettext('Lorem ipsum dolor sit amet, consectetur adipisicing ' +
                    'elit, sed do eiusmod tempor incididunt ut labore et ' +
                    'dolore magna aliqua. Ut enim ad minim veniam, quis ');

This does not work. makemessages stops at the first + sign, so in the .po file it shows up as:

msgid "Lorem ipsum dolor sit amet, consectetur adipisicing "

A bit of searching on the net lead to a style guide, which recommends the format we are already using for multi-line strings. But that style is not supported by makemessages.

I tried removing the + characters at the end of the lines. Without the + characters, makemessages can find the full string, but it no longer works in the browser.

Does there exist a style for multi-line strings, which is both supported by makemessages and can be expected to work in all major browsers?

So far I have found that what makemessages is actually doing is to replace all single-quoted strings with double-quoted strings and runs the result through xgettext claiming it to be C code.

1 Answer 1

7

The reason it doesn't work automatically is that makemessages doesn't use a real javascript parser. It does a minor transformation and applies a C parser. But in order to concatenate strings in javascript you need a + character, but in C you must not have any tokens between the strings to be concatenated.

I finally found a workaround, that works:

var $text = gettext('Lorem ipsum dolor sit amet, consectetur adipisicing ' //\
                    +
                    'elit, sed do eiusmod tempor incididunt ut labore et ' //\
                    +
                    'dolore magna aliqua. Ut enim ad minim veniam, quis ');

The javascript parser in the browser will see //\ as a comment, and find + characters between each string as needed. When using makemessages the \ character is parsed as line continuation, and both //\ as well as the + on the following line is considered to be a single comment. So the parser sees string constants separated by just a comment, and implicit string concatenation is performed.

I found this workaround by accident as I came across this piece of code from a fellow developer:

// IE8 only allows string, identifier and number keys between {}s
var parse_bool = {"null": null, "true": true, "false": false}
parse_bool[undefined] = null
parse_bool[null] = null            // using null/true/false *this* way works
parse_bool[true] = true            //  _______
parse_bool[false] = false          // ( WAT?! )
                                   //  ¯¯¯¯¯¯¯ o  ^__^
var render_bool = {}               //           o (oo)\_______
render_bool[null] = '--'           //             (__)\       )\/\
render_bool[true] = gettext('yes') //                 ||----w |
render_bool[false] = gettext('no') //                 ||     ||

When makemessages was processing this piece of javascript code, it missed the yes string.

Sign up to request clarification or add additional context in comments.

1 Comment

Speaking as the fellow developer, this is exactly why you put ASCII art cows in your code: it stress tests a lot of parsers. The fix of the sample code is of course to replace the <backslash> <slash> <backslash> cow tail with <slash> <backslash> <slash> :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.