On Tuesday, July 8, 2014 2:17:14 AM UTC+10, Staś Małolepszy wrote:
> Quoting Zibi Braniecki (2014-07-04 02:51:09)
>
> > That's an interesting problem. I think that originally we planned not
>
> > to allow developers to create nodes that cannot be replaced by the
>
> > localizer.
>
> > But your use case makes sense.
>
> >
>
> > Stas, do you have any opinion on what we should do here?
>
>
>
> That's a very interesting usecase indeed. I think there are four
>
> solutions that I'd like to explore:
>
>
>
> 1. Give more control to developers and third-party libs like Angular
>
> over when L20n's logic is run. This would allow to first translate
>
> a DOM element and then apply Angular's bindings. However, with the
>
> work we've been doing to put L20n into Mutation Observers and
>
> possibly into Shadow DOM, this would seem to be orthogonal to where
>
> we want to move L20n in the future.
>
>
>
> 2. Introduce a new data-l10n-* attribute, similar to what Igor
>
> suggested, that allows developers to control which descendants can
>
> be localized and which cannot, in a declarative manner.
>
>
>
> 3. Split our current DOM overlays implementation into two separate
>
> components:
>
>
>
> 1. text-level semantics, like <sup> and <em>, which localizers
>
> should always be able to use,
>
>
>
> 2. projected content declared by the developer in the source HTML
>
> as descendant elements, which localizers should be able to
>
> position inside of the translation; if developer allows it,
>
> they should also be able to provide the translation for the
>
> content of the element.
>
>
>
> 4. Improve the interaction between third-party libs (MV*) and L20n
>
> wrt. context data. For instance, the MV* framework could simpy
>
> change the context data used by L20n, and L20n would be responsible
>
> for retranslating the element and re-rendering it.
>
>
>
> So instead of this:
>
>
>
> <msg_forwarded_header """
>
> Forwarded message from <a></a>, <span></span>
>
> """>
>
>
>
> <div
>
> class="im_message_fwd_header"
>
> ng-if="historymessage._ == 'messageforwarded'"
>
> data-l20n="msg_forwarded_header">
>
> <a
>
> class="im_message_fwd_author"
>
> ng-click="openuser(historymessage.fwd_from_id)"
>
> ng-bind-html="historymessage.fwduser.rfirstname"></a>
>
>
>
> <span
>
> class="im_message_fwd_date"
>
> ng-bind="historymessage.fwd_date | dateortime"></span>
>
> </div>
>
>
>
> You'd do this:
>
>
>
> <msg_forwarded_header """
>
> Forwarded message from <a>{{ firstname }}</a>,
>
> <span>{{ date }}</span>
>
> """>
>
>
>
> <div
>
> class="im_message_fwd_header"
>
> ng-if="historymessage._ == 'messageforwarded'"
>
> data-l20n="msg_forwarded_header">
>
> <a
>
> class="im_message_fwd_author"
>
> ng-click="openuser(historymessage.fwd_from_id)"></a>
>
>
>
> <span
>
> class="im_message_fwd_date"></span>
>
> </div>
>
>
>
> document.l10n.updateData({
>
> firstname: historymessage.fwduser.rfirstname
>
> date: historymessage.fwd_date | dateortime
>
> });
>
>
>
> This will also make sure that the translation make sense
>
> grammatically with the new values of firstname and date.
>
>
>
>
>
> #2 is an easy solution but I'm a little bit reluctant to extending the
>
> public data-l10n-* API. #3 is something I'd like to give more thought
>
> to. As is #4, which looks compelling, but I'm uncertain of the
>
> performance consequences it may have.
>
>
>
> An interesting use-case indeed!
>
> -stas
>
>
>
> --
>
> @stas
Hi Stas, hello list!
I'm also in the process of adding L20n support to an Angular app and I thought
this discussion may be an appropriate place to add my thoughts.
First off, and probably most importantly, Angular does not play nicely with
other libraries which modify the DOM. Although it supports JQuery people are
often strongly discouraged from using it and are encouraged to use Angular
directives instead. If you absolutely have to mix other frameworks which modify
the DOM then you can wrap them in an Angular directive (which is what ng-l20n
does here: https://github.com/EE/ng-l20n/) however I'm not sure this is
appropriate for a cross-cutting concern like i18n.
It is also worth considering that when using a fully featured framework such as
Angular many, if not all, of the DOM manipulation code present in L20n (and the
io code) is likely duplicated in some form within the Angular code. It seems a
shame to force the client to download the extra bytes if they won't be used.
Perhaps it's better to strip out the io and html modules when integrating with
angular, and to re-create the functionality using Angular code.
An example of this kind of thinking would be how the Twitter Bootstrap
framework (http://getbootstrap.com/) was integrated with Angular. The CSS from
Bootstrap is still used but the Javascript code is not. Instead the project
reimplements the Bootstrap components using Angular directives
(http://angular-ui.github.io/bootstrap/). This way the user can still use
Bootstrap with Angular and not have to be concerned about race conditions, or
other peculiar behaviours, that would be introduced between the frameworks.
Angular developers are always writing custom directives, we love them! I have a
directive which combines a Bootstrap button, with an Angular-UI tooltip and a
Font-Awesome icon, here's an example:
<tooltip-button icon="save" tooltip="Save this comment"></tooltip-button>
I'm not sure if there is any way of applying l10n to the tooltip using the
standard L20n attributes here. Bear in mind that this may not exist in the html
source at all - Angular may just pull it into the document, at any point, at
any time.
I hope I have not already bored you out of the discussion with technical
details of Angular. I'd like to explain the relatively simple way that I have
integrated L20n with Angular.
I have removed the html module from L20n and slightly modified the bootstrap. I
have created an Angular "l20n" service which sets up and loads the default
locale and handles locale changes. I have created a "translate" directive and a
"translate" filter which works with a similar syntax to angular-translate
(https://github.com/angular-translate/angular-translate).
Here's some (mostly equivalent) examples based of the hello world example
(http://l20n.org/learn/hello-world/) using both the filter and directive.
<p data-translate="hello"></p>
<p translate="hello"></p>
<p translate>hello</p>
<p>{{ 'hello' | translate }}</p>
Using params (http://l20n.org/learn/using-external-variables-in-translations/):
<p data-translate="liked" data-translate-values="{user: 'Jane'}"></p>
<p translate="liked" translate-values="{user: 'Jane'}"></p>
<p translate="liked" translate-values="{user: session.userName}"></p>
<p translate="liked" translate-value-user="Jane"></p>
<p>{{ liked | translate : { user: 'Jane' } }}</p>
And finally a solution for my problematic tooltip above:
en.l20n
<save_comment "save this comment">
<tooltip-button icon="save" tooltip="{{ save_comment | translate
}}"></tooltip-button>
This Angular service works fine with the 1.0.0rc delivered by bower (so it is
recommended but not necessary to remove the html module) and also works fine if
you allow the resources to be loaded via the json manifest.
Please let me know if you find this interesting, I'd be able to set up a github
next week if you'd like to see it in action.
— paul
_______________________________________________
tools-l10n mailing list
[email protected]
https://lists.mozilla.org/listinfo/tools-l10n