grunt-angular-translate icon indicating copy to clipboard operation
grunt-angular-translate copied to clipboard

customRegex as object

Open Ulrikop opened this issue 9 years ago • 2 comments

Hi, I saw at master that I can use an object for customRegex. I was happy, because I searched a way to add prefix to some translation keys:

$stateProvider.state( /* i18nextract */ 'stateName', {
  ...
}

stateName should save as "navigation.state.statename".

So I added the following to the i18nextract options:

i18nextract: {
  default_options: {
    ...
    namespace: true,
    customRegex: {
      '\\/\\*\\s*i18nextract navigation-state\\s*\\*\\/\\s\'((?:\\\\.|[^\'\\\\])*)\': function(key) {
        return 'navigation.state.' + key;
      }
    }
  }
}

But that doesn't work. So I searched at the src of grunt-angular-translate, what I did wrong. So I found out, that this.data.customRegex is an empty object, when an object is set as customRegex.

I am not familiar with grunt task developing, so I can't find the failure. What do I do wrong?

When is it planed to build a tag with that new feature?

Thank you

edit: I use windows 10, node 4.4.0 grunt 0.4.5

Ulrikop avatar Mar 25 '16 10:03 Ulrikop

Hey @Ulrikop I'm currently in a trip with an Indian connection so I'll not be able to take care of this issue. I'll let you know ASAP what's going on.

My first insight:

  • v0.3.0 is an old version (pushed 23th, February 2015)
  • master got a lot of updates but there is still a refactor in progress (move core-lib to https://github.com/Boulangerie/angular-translate-extract and use it into this grunt plugin)

So the plan is for April:

  1. Finish refactoring https://github.com/Boulangerie/angular-translate-extract
  2. Move this project to https://github.com/Boulangerie/grunt-angular-translate
  3. Create https://github.com/Boulangerie/gulp-angular-translate

If you can @Ulrikop , install grunt-angular-translate#master to get this updates.

firehist avatar Mar 25 '16 10:03 firehist

Ohhh, f*** I found my problem. It was a configuration mistake. Sorry, sorry, sorry.

But i played around a little bit with the customRegex option and now I have a feature wish :-)

First: Can the customRegex get the match object (r in the src) as additional parameter? So the custom regex can use more match groups. Second: Can the customRegex return more keys as array?

Scenario: For some of my (ui.router) states I use the same template. All have a title and a description:

<h2>
  {{ 'state.' + stateName + '.title' | translate }}
</h2>
<div>
  {{ 'state.' + stateName + '.description' | translate }}
</div>

I want to use the state declaration for the i18n extraction. Therefore I add an enhanced version of the comment regex, so I can specify a prefix (here state) and optional one or more suffixes. Here is the state declaration with the comment:

$stateProvider.state( /* i18nextract state[title,description] */ 'stateName', {
  ...
}

My customRegex:

customRegex: {
  '\\/\\*\\s*i18nextract\\s*(\\w+(?:\\.\\w+)*)(?:\\[(\\w+(?:\\.\\w+)*(?:,\\w+(?:\\.\\w+)*)*)\\])?\\s*\\*\\/\\s\'(\\w+(?:\\.\\w+)*)\'': function(_, match) {
    var key = match[3];
    var prefix = match[1] + '.';

    if (match[2] === undefined) {
      return prefix + key;
    } else {
      var keys = [];

      match[2].split(',').forEach(function(suffix) {
        keys.push(prefix + key + '.' + suffix.trim());
      });

      return keys;
    }
  }
}

For that the _extractTranslation function must be changed in some places.

  1. The call of the function of custom regex must get the regex match as second parameter:

    translationKey = customRegex[regexName](translationKey, r) || translationKey;
    
  2. The translationKey can be a single string or an array with strings now. So the single string will be wrapped in an array and the call of defaultValueByTranslationKey must be inside a for each loop:

    if (!_.isArray(translationKey)) {
      translationKey = [translationKey];
    }
    
    _.forEach(translationKey, function(key) {
      // Avoid empty translation
      if (key === "") {
        return;
      }
    
      // Ternary operation
      var ternaryKeys = _extractTernaryKey(key)
      if (ternaryKeys) {
        _.forEach(ternaryKeys, function(v) {
          defaultValueByTranslationKey(v);
        });
      } else {
        defaultValueByTranslationKey(key, translationDefaultValue);
      }
    });
    
  3. The check to avoid empty translation is inside the for each loop now. It would be an improvement in the current version too. An empty string returned from the customRegex function is ignored at the moment. (Perhaps, an additional check for the type === string would be good, to avoid that the customRegex function returns something wrong).

Ulrikop avatar Mar 30 '16 19:03 Ulrikop