Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Variable Replacement Enhancement #188

Closed
totof3110 opened this issue Oct 11, 2013 · 12 comments
Closed

Variable Replacement Enhancement #188

totof3110 opened this issue Oct 11, 2013 · 12 comments

Comments

@totof3110
Copy link

The way to do variable replacement as described in http://pascalprecht.github.io/angular-translate/docs/en/#/guide/06_variable-replacement is a little cumbersome when the variables are dynamic: having to create a translationData object in the controller and pass it to the directive is a little too "intrusive", especially when all the objects needed are usually already in the $scope.

It would be really nice to be able to write something like:

<ANY translate="HELLO" translate-foo="currentUser.firstName"></ANY>

where:

// In the $translateProvider config.
var translations = {
    'HELLO': 'Hello {{foo}}!'
}

// In the controller.
$scope.currentUser = {
    'id': 123,
    'firstName': 'Pascal',
    'lastName': 'Precht'
};

I guess the directive would look at all required parameters and load them from the scope from a "namespaced" attribute (translate- + param name).

Would that even be possible?

Thanks!

@0x-r4bbit
Copy link
Member

Hey! You can pass dynamic data through translate directive by just using
mustache syntax. The dynamic value gets than interpolated and afterwards
used to determine the translation.

So translate="{{foo.bar}} " should do the trick.
On Oct 11, 2013 4:59 AM, "Christophe Levesque" notifications@github.com
wrote:

The way to do variable replacement as described in
http://pascalprecht.github.io/angular-translate/docs/en/#/guide/06_variable-replacementis a little cumbersome when the variables are dynamic: having to create a
translationData object in the controller and pass it to the directive is a
little too "intrusive", especially when all the objects I need are already
in the $scope.

It would be really nice to be able to write something like:

where:

// In the $translateProvider config.var translations = {
'HELLO': 'Hello {{foo}}!'}
// In the controller.$scope.currentUser = ;

I guess the directive would look at all required parameters and load them
from the scope from a "namespaced" attribute (translate- + param name).

Would that even be possible?

Thanks!


Reply to this email directly or view it on GitHubhttps://github.com//issues/188
.

@totof3110
Copy link
Author

True but that won't do message variable replacement will it? "translate="{{foo.bar}}" will translate the value of the scope variable foo.bar (whatever value that is) but there's no parameter being passed / replaced.

In my use case, I need to have some variable in the translatable message replaced with something variable (e.g. "Hello {{fisrtName}}"). Does that make sense?

@0x-r4bbit
Copy link
Member

@totof3110 Sorry, miss-read your question. So what you want, is actually a bit more declarative way to pass variable values through translate directive. Actually, the outcome would be pretty cool since one would be able to pass values in a pretty nice way and even without mustache syntax.

The downside would be that when having 3 or maybe 4 variables values, the usage of the directive could in such cases look like this:

<ANY
  translate="FOO"
  translate-foo="bar.baz"
  translate-bar="baz.bar"
  translate-baz="foo.bar"
  ></ANY>

However, in that kinda case, one would probably switch over to translate-values syntax and mustache.

Thinking about the implementation.. we have to compile the directive by hand since we have to determine what translate-* properties are configured. Unfortunately, we don't know what value identifier are inside of a translation id. Dynamic values get currently interpolated against strings completely blind, which means, you either provide all dynamic values that are needed, or not.

We also have to introduce a different type of value determination, since we wouldn't let angular (or actually interpolate directive) do the interpolation anymore for us. We now have expressions that Have to be evaluated.
There we have to make sure that we evaluate against the right scope, which isn't obviously when e.g. using this syntax inside of an ng-repeat or so.
The new syntax could also confuse users in some cases because translate-values only supports a string or an interpolation directive.

Another problem would be namespace conflicts. Regarding the example above, we have 3 different translate-* attributes, each of'em represents a value in any kind of way (currently an expression). Let's say we introduce another "built-in" attribute in the future. The introduction of a new attribute besides translate and translate-values could break your code when already using attributes in the translate-* namespace.

This means we have to at least introduce another namespace reserved for that kind of values. So sth. like translate-value-*.

So, I don't want to smash your idea down here. Actually, I like what you're requesting, since, like I said, the outcome would be pretty cool. I'm just thinking out loud.

I would like to ping @DWand and @knalli here and hear what they think about this feature.

@knalli
Copy link
Member

knalli commented Oct 11, 2013

  1. Voting for translate-value-* avoiding any namespace issues.
  2. The directive must look for all attributes on linking time (all attributes starting with translateValue…
  3. To avoid additional performance overhead, I would recommend NOT to add more watchers but instead extend the existing watcher expression. Going with me?

@0x-r4bbit
Copy link
Member

@knalli Agreed. Regarding point 3, we still need a solution for #169 which kinda goes hand in hand with existing watcher problems.

Extending the existing watcher requires the explicit properties on the scope, which is a bit tricky if we don't even know, which translate-value-* values are currently passed.

I think we have to rebuild the whole directive anyway to really make use of the advantages we actually should have when using a directive rather than a filter. Currently the directive sets up a watch which makes it not better as a filter unless we don't make any unwatch() there.

@DWand
Copy link
Member

DWand commented Oct 11, 2013

I'd like to say, that it looks interesting.
But, filters, directives and their life circle are what I'm actually not familiar now. I'm trying to get how these things work in Angular, but, you know, time is our worst enemy and js is not the only thing I'm working with. So, I can only say "in theory" here, sorry.
Anyway, it seems that the next angular-translate release would have a totally better directive(s) :)

@knalli
Copy link
Member

knalli commented Oct 11, 2013

Context "point 3"

Should work?

function link (scope, element, attrs) {
  var values = {};
  for (var key in attrs) {
    if (key.substr(0, 14) === 'translateValue') {
      values[key.substr(15)] = attrs[key];
    }
  }
}

@DWand
Copy link
Member

DWand commented Oct 11, 2013

And, as for the theme of this discussion, it would be also nice to provide a way to pass a js object literals to the directives/filters as a source of actual variables values. Saying "object literals" I also mean a possibility to use nested filter/directive calls with some params. Something like this: {{ val | filter : "{blah : "balh-blah-blah", blahblah : "Blah! {{ val2 | filter : "{onether_blah : "Blah..."}" }}"}" }}

@totof3110
Copy link
Author

@DWand : being able to filter message variable would be really nice too. Like:

<ANY translate="HELLO" translate-value-name="{{currentUser | fullName}}"></ANY>

where "fullName" is a filter that formats someone's name (e.g. preprend a particle like "Mr" or "Ms" depending on the gender of the user).

I'm not sure I understand your use-case that combines nested filters though... :-/

@DWand
Copy link
Member

DWand commented Oct 11, 2013

@totof3110 , I had tried to write a pluralization support based on the filter. So the use case is to be able to use filters in the translations for specific plural form. But it is a theme of the other discussion, haha )

0x-r4bbit added a commit that referenced this issue Dec 19, 2013
…attr

you're now able to add translate values via

```js
<ANY translate="TRANSLATION_ID"
     translate-value-foo="bar"
     translate-value-another="yay"
     ></ANY>
```

you're able to pass in a string or an interpolation so things like

```js
<ANY translate="TRANSLATION_ID"
     translate-value-foo="{{evaluate}}"
     ></ANY>
```

also work.

And yea this feature is progressive enhancement which means you can use it
along with `translate-values` as well without breaking your code. :)

Fixes #188
@0x-r4bbit
Copy link
Member

Hey @totof3110 you feature request just landed in canary :)

@totof3110
Copy link
Author

Awesome! Thanks @PascalPrecht! I'll give it a shot ASAP. :)

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

No branches or pull requests

4 participants