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

Support i18n in templates. #150

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Support i18n in templates. #150

wants to merge 3 commits into from

Conversation

ernie
Copy link
Contributor

@ernie ernie commented May 20, 2013

  • To HTML-escape an i18n string: {{% some.key.name }}
  • To return an i18n string unmodified: {{$ some.key.name }}

i18n keys are loaded from the "mustache" namespace by default. This is because they support etags and utags, which are not the standard means of i18n interpolation.

Options relating to translation:

  • i18n_namespace - Sets the namespace containing a Mustache's i18n keys * locale - Override translation locale during render (I18n.locale by default)
  • translate_only - Allow for a two-pass rendering setup, by only expanding partials and expanding i18n keys to their translation. In this way, translation may be done server-side but final rendering may be done client-side, via Mustache.js or another implementation that does not (yet?) support i18n.

Some caveats:

  • Use of tags other than {{}} and {{{}}} inside an i18n string has unspecified behavior. It certainly isn't intended to work, so any success had is purely by accident.
  • Use of translate_only option means you will blow the stack if you use recursive partials, for obvious reasons.

Rationale:

While it's possible to implement I18n by handling translations in each view class, it's less than optimal to do so. If you want to support true i18n interpolation, then you're forced to provide interpolation variables from within the view class, and the view class may not have access to all the information required to supply those variables.

An alternative is to use lambda return values, which of course could perform the translation as a filter, but this is somewhat more laborious, since the responsibility is now on the user to create a mapping between the attributes of the view and those inside the locale file.

Regarding the implementation itself:

I chose % as the sigil both because its appearance brings to mind both the current %{} interpolation syntax and the notion of key/value pairs in general (to this former Perl guy). $ was chosen for the unescaped version for proximity to %.

The translate_only option is, perhaps, the most questionable feature here. Its presence stems from a real-world use case in an app I'm working on, but I realize I may well be the edge case here and would be happy to remove this functionality if is proves too odd. It certainly created a few wrinkles in the implementation that could otherwise be avoided. In fact, I just went ahead and created a branch that doesn't contain the translate_only option, for comparison.

One thing I did take the opportunity to do, while I was in here, was improve the handling of lambda return values to a section tag. While the LoD violation here is a bit offputting, and could certainly be refactored out, I find the notion of setting the otag and ctag on a tokenizer for the template to be more readable than defining a singleton method which then must duplicate the logic in the Template class's tokens method with modifications.

ernie added 3 commits May 19, 2013 22:16
* To HTML-escape an i18n string: {{% some.key.name }}
* To return an i18n string unmodified: {{$ some.key.name }}

i18n keys are loaded from the "mustache" namespace by default. This is
because they support etags and utags, which are not the standard means
of i18n interpolation.

Options relating to translation:

* i18n_namespace - Sets the namespace containing a Mustache's i18n keys
* locale - Override translation locale during render (I18n.locale by
  default)
* translate_only - Allow for a two-pass rendering setup, by only
  expanding partials and expanding i18n keys to their translation. In
  this way, translation may be done server-side but final rendering may
  be done client-side, via Mustache.js or another implementation that
  does not (yet?) support i18n.

Some caveats:

* Use of tags other than {{}} and {{{}}} inside an i18n string has
  unspecified behavior. It certainly isn't *intended* to work, so any
  success had is purely by accident.
* Use of translate_only option means you will blow the stack if you use
  recursive partials, for obvious reasons.

Rationale:

While it's possible to implement I18n by handling translations in each
view class, it's less than optimal to do so. If you want to support true
i18n interpolation, then you're forced to provide interpolation
variables from within the view class, and the view class may not have
access to all the information required to supply those variables.

An alternative is to use lambda return values, which of course could
perform the translation as a filter, but this is somewhat more
laborious, since the responsibility is now on the user to create a
mapping between the attributes of the view and those inside the locale
file.

Regarding the implementation itself:

I chose `%` as the sigil both because its appearance brings to mind both
the current `%{}` interpolation syntax and the notion of key/value pairs
in general (to this former Perl guy). `$` was chosen for the unescaped
version for proximity to `%`.

The `translate_only` option is, perhaps, the most questionable feature
here. Its presence stems from a real-world use case in an app I'm
working on, but I realize I may well be the edge case here and would be
happy to remove this functionality if is proves too odd. It certainly
created a few wrinkles in the implementation that could otherwise be
avoided.

One thing I did take the opportunity to do, while I was in here, was
improve the handling of lambda return values to a section tag. While the
LoD violation here is a bit offputting, and could certainly be
refactored out, I find the notion of setting the otag and ctag on a
`tokenizer` for the template to be more readable than defining a
singleton method which then must duplicate the logic in the Template
class's tokens method with modifications.
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

Successfully merging this pull request may close these issues.

None yet

1 participant