smhg / gettext-swig

Extract translatable strings from Swig template strings.
MIT License
1 stars 2 forks source link

[NFR] Add variable string interpolator format #2

Closed dschissler closed 9 years ago

dschissler commented 9 years ago

swig-i18n-abide supports a rather nice %s, %d format with {% trans "String %(foobar)s with string replacements" %}.

I think that '%(var)s' format might be idea for variable strings. So then the Swig parser would just need to collapse '%(var)(s|d)' to '%(s|d)' for the extracted message.

smhg commented 9 years ago

As I understand it, you are looking for variable replacement? This is the task of the trans tag (aka helper).

In the example above String %(foobar)s with string replacements is what needs to go to Poedit for translation and what this parser outputs.

dschissler commented 9 years ago

Sure the helper needs to be created but without support for this in the xgettext part it will extract the entire 'String %(foobar)s with string replacements' but variable foobar isn't relevant there and doesn't match typical gettext strings. The foobar variable is internal application state and doesn't belong in the extracted messages. With this format assuming that the helper has access to the template variable context then it can be replaced from there.

Another possibility is if gettext-swig can handle parameters past the keyword spec, with + 1 for the count parameter, then extra variables can be passed into the helper for sprintf style replacing of %s and %d.

Its pretty limiting without some way of supporting replacement.

smhg commented 9 years ago

As far as I know, you typically use something like %s (a string variable) en %1$s (first string variable) in your translatable strings (PHP's sprintf placeholder formatting). The gettext parser/translation application doesn't care about this.

So, yes, you end up with "Something %s something else" as a translatable string in Poedit. Which is what you want.

Which placeholder format (sprintf or different) you use is left to your template language's string replacement support or your custom translation helper.

dschissler commented 9 years ago

Here is something typical from code:

$subjectMsg = sprintf($translate->gettext('Please confirm your email on %s'), $domain);

So in a template tag there needs to be some way to specify which variables you are passing into an sprintf-like function in the helper. There are infinite options in raw code but in a template it needs something different. I like the "%(var)s" approach because its very concise. If the xgettext part understands the notation then it can ignore the specific variable and just return the normal string. The helper will become a bit more complicated but that isn't your issue. All that you would have to do is replace "%(var)s" with "%s" and return that.

smhg commented 9 years ago

I really think it isn't a good idea to add this kind of logic to a gettext parser. I agree that %s sounds easier to reason about for a translator. But in pure PHP you are also able to write your translatable strings like "Please confirm your email on $domain".

If Swig doesn't allow you to work with sprintf-style placeholders and you prefer them, maybe Swig isn't the best option. But wouldn't something like this work:

{% translate "Please confirm your email on %s" domain %}

Since you have to create the translate helper/tag yourself anyhow, you can get this to work, no?

dschissler commented 9 years ago

Since you have to create the translate helper/tag yourself anyhow, you can get this to work, no?

Yes that would work. I would just need to not use a generic x:1,2 format for everything; ex _:1,2. So for example I would use t and n:1,2 for my keywords. As long as this parser properly uses the keyword spec and ignores other arguments then it should work out fine.

So sure that is not a big deal and is a real easy solution. I ask that you keep this issue open for a while to collect additional insight.

smhg commented 9 years ago

It is definitely a requirement for the parser to properly use the keyword spec (and indeed ignoring arguments not in it).

Parsing the contents of strings really sounds like a step to far. On one side: I can't imagine the "traditional" xgettext to ever do this. On the other side: each (template) language of course has it's own quirks. But in the case of Swig I think it makes sense to stay away from it. Because:

  1. You are able to write your helpers/tags in an alternative format (above).
  2. It generally isn't "forbidden" to have variables in your translatable strings. As shown in the raw-PHP example above.

Without wanting to sound too decisive, I'm going to close this. Should 1. however not turn out to be possible, please post your findings.