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

Create one file per component.

Open reppners opened this issue 9 years ago • 7 comments

With angular 2 going the component oriented approach to building applications I would like to have the possibility to extract translation keys per component so I end up with a file set that is loadable with the partial loader as documented in the angular-translate docs here.

The end result would be one json-file per component. A component may be contained in a folder and consists of an template (html, svg) file and a code file (ts, js, cs). The same rule could apply for services and filter/pipes that use the $translate service. One code file -> corresponding json-file.

reppners avatar Oct 30 '15 10:10 reppners

I've come here with similar questions. Just toying with ideas on what approach to take at the moment.

Each of our "components" has its own module, with the component-directive, controller, services etc associated with it.

For now, we're simply attaching a config block to the component module and providing translations using $translateProvider.

Each of our components contains its own translation data, rather than it relying on the parent app to provide the translations.

So, at the moment, do you have a single file with the translations for your whole app?

peterhodges avatar Dec 11 '15 16:12 peterhodges

Don't get really well this issue. So @reppners question is: Can we separate translation output into separated files ?

If this is the question, the answer could be yes. You can have multiple config for this tasks and parse your files per component's folder.

firehist avatar Feb 23 '16 10:02 firehist

@firehist Yes, you got it right.

So you're saying its simply a matter of configuring the grunt/gulp task by using e.g. the rename function in grunt?

i18nextract: {
  per_component: {
    lang:     ['fr_FR'],
    files: [
        {
          expand: true,     // Enable dynamic expansion.
          cwd: 'src/',      // Src matches are relative to this path.
          src: ['**/*.js', '**/*.html'], // Actual pattern(s) to match.
          dest: 'assets/i18n',   // Destination path prefix.
          ext: '.json',   // Dest filepaths will have this extension.
          rename: function(dest, src) {
            // return the same dest filename for each component
          }
        },
      ],
  }
}

On second thought thats really an obvious solution. I will try that out, thx :)

reppners avatar Feb 23 '16 16:02 reppners

I tried the following:

per_component: {
                namespace: true,
                defaultLang: "de-DE",
                lang: ["en-US"],
                files: [{
                    expand: true,
                    src: ["src/**/*.js", "src/**/*.html"],
                    ext: ".json"
                }]
            }

Having implemented a few grunt tasks myself I know this should result in arrays of src files that map to one destination file per component when the files have all the same name per component but only differ in extension (which is true for my case), but I get the following error: Warning: Cannot read property 'indexOf' of undefined Use --force to continue.

reppners avatar Feb 23 '16 16:02 reppners

@reppners came across the same problem. Have you already found a solution?

haschu avatar Apr 21 '16 12:04 haschu

@haschu No

reppners avatar Apr 21 '16 12:04 reppners

Turns out, that grunt-angular-translate doesn't support the files array. However, you could workaround your problem as @firehist has mentioned, by using multiple configs (one per each file/module).

To avoid doing this manually for each module/component you could build a wrapper task.

I did something like this:

  var i18nextractConfigs = {};

  // Generate i18nextract configs
  grunt.file.expand( "app/**/*.html" ).forEach( function( template ) {
    var arrTemplate = template.split( "/templates/" ),
        dest = arrTemplate[ 0 ] + "/lang",
        src = template;

    i18nextractConfigs[ src ] = {
      src: src,
      lang: [ "en" ],
      dest:  dest,
      namespace: true,
      safeMode: true // avoid overwriting translation files for the same module
    };
  });

  grunt.initConfig({
    i18nextract: i18nextractConfigs
  });

For example, if you have an app structure like this:

- app
  - modules
     - moduleA
       - foo
       - bar
       - templates
         - someTpl.html
     - moduleB
       - foo
       - bar
       - templates
         - someTpl.html

The code above scans all ".html" files in your "app" directory and will create a "lang" sibling directory for each "template" directory:

- app
  - modules
     - moduleA
       - foo
       - bar
       - lang
         - en.json
       - templates
         - someTpl.html
     - moduleB
       - foo
       - bar
       - lang
         - en.json
       - templates
         - someTpl.html

Hope that gives some ideas on how the problem could be solved.

haschu avatar Apr 21 '16 14:04 haschu