Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

grunt-localizr

Package Overview
Dependencies
Maintainers
4
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-localizr - npm Package Compare versions

Comparing version 0.1.4 to 0.2.0

lib/localeList.js

8

lib/utils.js

@@ -8,6 +8,3 @@ 'use strict';

getName: function getName (filePath, root) {
var fileInfo = {},
relative = module.exports.getRelative(filePath, root),
paths;
var relative = module.exports.getRelative(filePath, root);
return relative.replace(path.extname(relative), '');

@@ -17,5 +14,4 @@ },

getRelative: function getRelative (filePath, root) {
var relative = filePath.replace(root, '');
return relative.substr(1);
return filePath.replace(root, '').substr(1);
}
};
{
"name": "grunt-localizr",
"version": "0.1.4",
"version": "0.2.0",
"author": {

@@ -13,2 +13,3 @@ "name": "Poornima Venkatakrishnan",

"dependencies": {
"bluebird": "^2.9.3",
"concat-stream": "~1.4.3",

@@ -18,11 +19,11 @@ "graceful-fs": "~2.0.2",

"mkdirp": "~0.3.5",
"q": "~1.0.0",
"qlimit": "^0.1.1"
},
"devDependencies": {
"tape": "^2.12.0",
"rimraf": "^2.2.6",
"grunt": "^0.4.4",
"grunt-force-task": "^1.0.0",
"istanbul": "^0.2.6",
"jshint": "^2.4.4",
"grunt": "^0.4.4"
"rimraf": "^2.2.6",
"tape": "^2.12.0"
},

@@ -29,0 +30,0 @@ "scripts": {

@@ -8,2 +8,39 @@ grunt-localizr

A grunt task to support i18n using localizr module.
A grunt task to support i18n using localizr module for dust templates. i18n is solved the way kraken supports today using `.properties` files.
The [localizr](https://github.com/krakenjs/localizr) module is a tool to apply localization to dust templates before rendering.
This plugin uses that localizr module, and scans your project under the root app directory for
* `.dust` files in `public/templates`
* `.properties` content files for corresponding `.dust` files in `locales/` folder
and puts the localized files in `tmp/` dir.
For example:
Localizing `public/templates/foo/bar.dust` with `locales/US/en/foo/bar.properties` will generate `tmp/US/en/foo/bar.dust`
##Usage
In your Gruntfile.js
```
module.exports = function localizr(grunt) {
// Load task
grunt.loadNpmTasks('grunt-localizr');
// Options
return {
files: ['public/templates/**/*.dust'],
options: {
contentPath: ['locales/**/*.properties']
}
};
};
```
## Using with kraken 1.0 apps
If you use [generator-kraken](git@github.com:krakenjs/generator-kraken.git) for scaffolding your kraken apps, you will see
that the generated `Gruntfile.js` will be automatically setting up the i18n task for you.

@@ -21,3 +21,3 @@ /*───────────────────────────────────────────────────────────────────────────*\

var path = require('path'),
Q = require('q'),
BB = require('bluebird'),
utils = require('../lib/utils'),

@@ -29,2 +29,3 @@ mkdirp = require('mkdirp'),

fs = require('fs'),
localeList = require('../lib/localeList'),
logger;

@@ -44,7 +45,5 @@

grunt.registerMultiTask('localizr', 'A preprocessor for Dust.js templates.', function () {
var done, options, contentPath, bundles, bundleRoot, filesSrc,
var done, options, contentPath, bundleRoot, filesSrc,
pathName = path.sep + '**' + path.sep + '*.properties',
fileRoot = this.options().templateRoot || path.join('public', 'templates'),
propFile = this.options().contentFile,
promise;
fileRoot = this.options().templateRoot || path.join('public', 'templates');

@@ -64,3 +63,2 @@ done = this.async();

//console.info('contentPath:', contentPath);
filesSrc = this.filesSrc.map(correctPathSeparator);

@@ -81,11 +79,22 @@ contentPath = contentPath.map(function (cp) {

bundleRoot = Array.isArray(bundleRoot) ? bundleRoot[0] : bundleRoot;
bundles = (grunt.file.expand(contentPath)).map(correctPathSeparator);
Q.all(filesSrc.map(function (srcFile) {
return processSrcDust(srcFile, bundles, bundleRoot, options);
})).then(done);
localeList(path.join(process.cwd(), bundleRoot), function (err, locales) {
if (err) {
logger.error('Terminating due to err', err);
done(err);
return;
}
BB.all(filesSrc.map(function (srcFile) {
return processSrcDust(srcFile, locales, bundleRoot, options);
}))
.then(done)
.catch(function (err) {
logger.error('Terminating due to err', err);
done(err);
});
});
});
};
function processSrcDust(srcFile, bundles, bundleRoot, options) {
var deferred = Q.defer(),
function processSrcDust(srcFile, locales, bundleRoot, options) {
var deferred = BB.pending(),
fileBundles,

@@ -97,8 +106,11 @@ name = utils.getName(srcFile, options.fileRoot),

//get the bundles that correspond to this file
fileBundles = bundles.filter(function (entry) {
return (entry.indexOf(propName) !== -1);
});
fileBundles = locales.map(function (entry) {
return path.join(bundleRoot, entry, propName);
}).filter(function (entry) {
return fs.existsSync(path.join(process.cwd(), entry));
});
if (fileBundles.length === 0) {
dustPromises = dustPromises.concat(processWhenNoBundles(bundles, bundleRoot, srcFile, name, options));
dustPromises = dustPromises.concat(processWhenNoBundles(locales, srcFile, name, options));

@@ -108,3 +120,3 @@ } else {

}
Q.all(dustPromises).then(function () {
BB.all(dustPromises).then(function () {
deferred.resolve();

@@ -116,17 +128,7 @@ });

function processWhenNoBundles(bundles, bundleRoot, srcFile, name, options) {
return bundles.map(function (entry) {
var arr = entry.split(path.sep);
arr.pop();
arr.shift();
if (arr.length > 2) {
arr = arr.slice(0, 2);
}
return arr.join(path.sep);
}).filter(function (entry, index, self) {
return (self.indexOf(entry) === index);
}).map(function (entry) {
var destFile = path.join(process.cwd(), options.tmpDir, entry, name + '.dust');
return copy(srcFile, destFile);
});
function processWhenNoBundles(locales, srcFile, name, options) {
return locales.map(function (entry) {
var destFile = path.join(process.cwd(), options.tmpDir, entry, name + '.dust');
return copy(srcFile, destFile);
});
}

@@ -148,6 +150,5 @@

},
deferred = Q.defer();
deferred = BB.pending();
srcFile = path.join(process.cwd(), srcFile);
propFile = path.join(process.cwd(), propFile);
destFile = path.join(process.cwd(), destFile);

@@ -158,5 +159,6 @@

if (err) {
deferred.reject(err);
logger.error('Failed to generate', srcFile, ' from ', destFile, 'error', err, '\n');
deferred.resolve(); //we want to continue with compiling other templates
logger.error('Failed to generate', destFile, ' from ', srcFile, 'error', err, '\n');
return;
}

@@ -166,16 +168,23 @@ var out = concat({ encoding: 'string' }, function (data) {

if (err) {
deferred.reject(err);
logger.error('Failed to generate', srcFile, ' from ', destFile, 'error', err, '\n');
deferred.resolve(); //we want to continue with compiling other templates
logger.error('Failed to generate', destFile, ' from ', srcFile, 'error', err, '\n');
return;
}
deferred.resolve(destFile);
logger.write('Generated ', destFile, '\n');
deferred.resolve(destFile);
});
});
localizr.createReadStream(opt).pipe(out);
localizr.createReadStream(opt)
.on('error', function (err) {
logger.error('Error while localizing with ', srcFile, ' and ', propFile);
deferred.resolve(); //we want to continue with the compiling other templates
})
.pipe(out)
.on('error', function (err) {
logger.error('Error while localizing with ', srcFile, ' and ', propFile);
deferred.resolve(); //we want to continue with compiling other templates
});
});
return deferred.promise;

@@ -185,3 +194,3 @@ }

var copy = qlimit(function copy(srcFile, destFile) {
var deferred = Q.defer();
var deferred = BB.pending();
mkdirp(path.dirname(destFile), function (err) {

@@ -194,7 +203,7 @@ if (err) {

fs.createReadStream(srcFile).pipe(fs.createWriteStream(destFile)
.on('finish', function() {
.on('finish', function () {
logger.write('Generated ', destFile, '\n');
deferred.resolve();
}).on('error', function(err) {
logger.write('Failed to generate', destFile, '\n');
}).on('error', function (err) {
logger.error('Failed to generate', destFile, '\n');
deferred.reject(err);

@@ -201,0 +210,0 @@ }));

@@ -8,6 +8,7 @@ 'use strict';

grunt.loadNpmTasks('grunt-force-task');
test('Grunt-localizr', function (t) {
process.chdir(path.join(process.cwd(), 'test', 'fixtures'));
grunt.task.init = function() {};
require('../tasks/index')(grunt);

@@ -24,3 +25,2 @@ t.test('test a localizr build', function(t) {

require('../tasks/index')(grunt);
grunt.tasks(['localizr'], {}, function(){

@@ -57,3 +57,2 @@ //verify the files exist

require('../tasks/index')(grunt);
grunt.tasks(['localizr'], {}, function(){

@@ -74,2 +73,50 @@ //verify the files exist

});
t.test('test a localizr build with three templates same name/ different dir , 2 with .properties file, 1 with no .properties, ' +
'also makes sure absence of a properties file for a locale does not break the build', function(t) {
grunt.initConfig({
localizr: {
files: ['cornercase/templates/**/*.dust'],
options: {
contentPath: ['cornercase/locales/**/*.properties'],
templateRoot: 'cornercase/templates'
}
}
});
grunt.tasks(['localizr'], {}, function(){
//verify the files exist
t.equal(true, fs.existsSync('./tmp/US/en/test.dust'));
t.equal(true, fs.existsSync('./tmp/US/en/nested1/test.dust'));
t.equal(true, fs.existsSync('./tmp/US/en/nested2/test.dust'));
t.equal(false, fs.existsSync('./tmp/US/fr/test.dust'));
//verify they have expected content
t.equal('<div>Hola</div>', fs.readFileSync('./tmp/US/es/test.dust', 'utf8'));
t.equal('<div>I am translated to algo</div>', fs.readFileSync('./tmp/US/es/nested1/test.dust', 'utf8'));
t.equal('<div>I am cool and don\'t need any pre tags</div>', fs.readFileSync('./tmp/US/en/nested2/test.dust', 'utf8'));
rimraf('tmp', function() {
t.end();
});
});
});
t.test('test wrong root path', function(t) {
grunt.initConfig({
localizr: {
files: ['errorcase/templates/**/*.dust'],
options: {
contentPath: ['errorcase/locales/**/*.properties'],
templateRoot: 'errorcase/templates'
}
}
});
grunt.tasks(['force:localizr'], {}, function() {
t.end();
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc