Reputation: 636
I'm looking for the best way to combine json files maintaining certain structure using Grunt.
The files are disposed in folders in a structure like this:
App ├── locales │ ├── en │ │ └── translation.json │ ├── es │ │ └── translation.json │ └── fr │ └── translation.json └── widgets ├── Posts │ └── locales │ ├── en │ │ └── translation.json │ ├── es │ │ └── translation.json │ └── fr │ └── translation.json ├── Comments │ └── locales │ ├── en │ │ └── translation.json │ ├── es │ │ └── translation.json │ └── fr │ └── translation.json └── Links ├── locales │ ├── en │ │ └── translation.json │ ├── es │ │ └── translation.json │ └── fr │ └── translation.json
And the desired output with the files merged would be:
App │ ├── lang │ ├── en │ │ └── translation.json │ ├── es │ │ └── translation.json │ └── fr │ └── translation.json ├── locales └── widgets
So far I came up with one solution using grunt-contrib-concat, but I think there should be a better way to do it.
concat: {
translateEN: {
src: [
'www/js/app/locales/en/*.json',
'www/js/app/widgets/posts/locales/en/*.json',
'www/js/app/widgets/comments/locales/en/*.json',
'www/js/app/widgets/links/locales/en/*.json'
],
dest: 'www/js/app/lang/en/translation.json',
options: {
banner: '{',
footer: "}",
separator: ','
}
},
translateES: {
src: [
'www/js/app/locales/es/*.json',
'www/js/app/widgets/posts/locales/es/*.json',
'www/js/app/widgets/comments/locales/es/*.json',
'www/js/app/widgets/links/locales/es/*.json'
],
dest: 'www/js/app/lang/es/translation.json',
options: {
banner: '{',
footer: "}",
separator: ','
}
},
translateFR: {
src: [
'www/js/app/locales/fr/*.json',
'www/js/app/widgets/posts/locales/fr/*.json',
'www/js/app/widgets/comments/locales/fr/*.json',
'www/js/app/widgets/links/locales/fr/*.json'
],
dest: 'www/js/app/lang/fr/translation.json',
options: {
banner: '{',
footer: "}",
separator: ','
}
}
}
Upvotes: 4
Views: 2205
Reputation: 636
I ended up writting my own grunt task for this:
grunt.task.registerMultiTask('buildLocales', 'Build Locale files.', function() {
var that = this,
len = this.filesSrc.length,
outputDir,
outputFile,
originalFile,
destFile,
merged;
var jsonConcat = function(object1, object2) {
var key, a1, a2;
for (key in object2) {
if (object2.hasOwnProperty(key)) {
a2 = object2[key];
a1 = object1[key];
if (a1) {
a1.push.apply(a1, a2);
} else {
object1[key] = a2;
}
}
}
return object1;
};
var iterateTroughFiles = function(abspath, rootdir, subdir, filename){
if (abspath.indexOf('/.svn') === -1){
outputDir = that.data.dest + '/' + subdir;
outputFile = outputDir + '/' + filename;
// If output dir doesnt exists, then create it
if (!grunt.file.exists(outputDir)) {
grunt.file.mkdir(outputDir);
}
originalFile = grunt.file.readJSON(abspath);
// if dest file doenst exist, then just copy it.
if (!grunt.file.exists(outputFile)) {
grunt.file.write(outputFile, JSON.stringify(originalFile));
} else {
// read source file, read dest file. merge them. write it in dest file
destFile = grunt.file.readJSON(outputFile);
merged = jsonConcat(destFile, originalFile);
grunt.file.write(outputFile, JSON.stringify(merged));
}
}
};
for (var x = 0; x < len; x++) {
grunt.file.recurse(this.filesSrc[x], iterateTroughFiles);
}
});
And the implementation is something like this:
buildLocales: {
locales:{
src: [
'www/js/app/**/locales'
],
dest: PATH_BUILD_LANGUAGES
}
},
Upvotes: 2