Merge pull request #961 from chrisgarrity/gh940-missing-i18n

[Master] Hotfix - update build-locales script
This commit is contained in:
Matthew Taylor 2016-10-16 22:36:51 -04:00 committed by GitHub
commit 67d62cc4c1
10 changed files with 89 additions and 22 deletions

View file

@ -86,7 +86,7 @@ for (var v in routes) {
if (typeof routes[v].redirect !== 'undefined') { if (typeof routes[v].redirect !== 'undefined') {
continue; continue;
} }
views.push(routes[v].name); views.push(routes[v].name);
try { try {
var subdir = routes[v].view.split('/'); var subdir = routes[v].view.split('/');
@ -97,7 +97,8 @@ for (var v in routes) {
en: ids en: ids
}; };
idsWithICU = merge(idsWithICU, localeCompare.idToICUMap(routes[v].name, ids)); idsWithICU = merge(idsWithICU, localeCompare.idToICUMap(routes[v].name, ids));
icuWithIds = merge(icuWithIds, localeCompare.icuToIdMap(routes[v].name, ids)); // Note: if lodash.merge gets updated to 4.0 or higher this needs to be mergeWith instead
icuWithIds = merge(icuWithIds, localeCompare.icuToIdMap(routes[v].name, ids), localeCompare.customMerge);
} catch (err) { } catch (err) {
if (err.code !== 'MODULE_NOT_FOUND') { if (err.code !== 'MODULE_NOT_FOUND') {
throw err; throw err;

View file

@ -6,6 +6,7 @@ var crypto = require('crypto');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var po2icu = require('po2icu'); var po2icu = require('po2icu');
var isArray = require('lodash.isarray');
var Helpers = {}; var Helpers = {};
@ -20,6 +21,21 @@ Helpers.getMD5 = function (string) {
return crypto.createHash('md5').update(cleanedString, 'utf8').digest('hex'); return crypto.createHash('md5').update(cleanedString, 'utf8').digest('hex');
}; };
/**
* Customizer for icuWithIds merge.
* If icu key already has an id value, concatenate additional ids instead
* of replacing.
*
* @param {array} objVal current value
* @param {string} srcVal new value
* @return {array} objVal with srcVal concatenated
*/
Helpers.customMerge = function (objVal, srcVal) {
if (isArray(objVal)) {
return objVal.concat(srcVal);
}
};
/* /*
Existing translations should be in the key value format specified by react-intl (i.e. Existing translations should be in the key value format specified by react-intl (i.e.
formatted message id, with icu string as the value). New Translations should be in the formatted message id, with icu string as the value). New Translations should be in the
@ -33,7 +49,9 @@ Helpers.mergeNewTranslations = function (existingTranslations, newTranslations,
for (var id in newTranslations) { for (var id in newTranslations) {
var md5 = Helpers.getMD5(id); var md5 = Helpers.getMD5(id);
if (md5Map.hasOwnProperty(md5) && newTranslations[id].length > 0) { if (md5Map.hasOwnProperty(md5) && newTranslations[id].length > 0) {
existingTranslations[md5Map[md5]] = newTranslations[id]; md5Map[md5].forEach(function (msgId) {
existingTranslations[msgId] = newTranslations[id];
});
} }
} }
@ -103,7 +121,7 @@ Helpers.getTranslationsForLanguage = function (lang, idsWithICU, md5WithIds, sep
throw err; throw err;
} }
} }
var translationsByView = {}; var translationsByView = {};
for (var id in translations) { for (var id in translations) {
var ids = id.split(separator); // [viewName, stringId] var ids = id.split(separator); // [viewName, stringId]
@ -132,7 +150,7 @@ Helpers.writeTranslationsToJS = function (outputDir, viewName, translationObject
Helpers.idToICUMap = function (viewName, ids, separator) { Helpers.idToICUMap = function (viewName, ids, separator) {
var idsToICU = {}; var idsToICU = {};
separator = separator || ':'; separator = separator || ':';
for (var id in ids) { for (var id in ids) {
idsToICU[viewName + separator + id] = ids[id]; idsToICU[viewName + separator + id] = ids[id];
} }
@ -146,7 +164,7 @@ Helpers.icuToIdMap = function (viewName, ids, separator) {
separator = separator || ':'; separator = separator || ':';
for (var id in ids) { for (var id in ids) {
icuToIds[ids[id]] = viewName + separator + id; icuToIds[ids[id]] = [viewName + separator + id];
} }
return icuToIds; return icuToIds;
}; };

View file

@ -59,6 +59,7 @@
"keymirror": "0.1.1", "keymirror": "0.1.1",
"lodash.clone": "3.0.3", "lodash.clone": "3.0.3",
"lodash.defaultsdeep": "3.10.0", "lodash.defaultsdeep": "3.10.0",
"lodash.isarray": "3.0.4",
"lodash.merge": "3.3.2", "lodash.merge": "3.3.2",
"lodash.omit": "3.1.0", "lodash.omit": "3.1.0",
"lodash.range": "3.0.1", "lodash.range": "3.0.1",

View file

@ -11,8 +11,7 @@ require('./activity.scss');
var defaultMessages = defineMessages({ var defaultMessages = defineMessages({
whatsHappening: { whatsHappening: {
id: 'general.whatsHappening', id: 'general.whatsHappening'
defaultMessage: 'What\'s Happening?'
} }
}); });

View file

@ -215,11 +215,11 @@ var Splash = injectIntl(React.createClass({
<Box <Box
key="curator_top_projects" key="curator_top_projects"
title={ title={
'Projects Curated by ' + formatMessage({id: 'splash.projectsCuratedBy'}) +
this.state.featuredGlobal.curator_top_projects[0].curator_name} this.state.featuredGlobal.curator_top_projects[0].curator_name}
moreTitle={formatMessage({id: 'general.learnMore', defaultMessage: 'Learn More'})} moreTitle={formatMessage({id: 'general.learnMore'})}
moreHref="/studios/386359/"> moreHref="/studios/386359/">
<Carousel items={this.state.featuredGlobal.curator_top_projects} /> <Carousel items={this.state.featuredGlobal.curator_top_projects} />
</Box> </Box>
); );
@ -234,9 +234,9 @@ var Splash = injectIntl(React.createClass({
title={ title={
formatMessage({id: 'splash.scratchDesignStudioTitle'}) formatMessage({id: 'splash.scratchDesignStudioTitle'})
+ ' - ' + this.state.featuredGlobal.scratch_design_studio[0].gallery_title} + ' - ' + this.state.featuredGlobal.scratch_design_studio[0].gallery_title}
moreTitle={formatMessage({id: 'splash.visitTheStudio', defaultMessage: 'Visit the studio'})} moreTitle={formatMessage({id: 'splash.visitTheStudio'})}
moreHref={'/studios/' + this.state.featuredGlobal.scratch_design_studio[0].gallery_id + '/'}> moreHref={'/studios/' + this.state.featuredGlobal.scratch_design_studio[0].gallery_id + '/'}>
<Carousel items={this.state.featuredGlobal.scratch_design_studio} /> <Carousel items={this.state.featuredGlobal.scratch_design_studio} />
</Box> </Box>
); );
@ -260,7 +260,7 @@ var Splash = injectIntl(React.createClass({
rows.push( rows.push(
<Box title={formatMessage({id: 'splash.projectsByScratchersFollowing'})} <Box title={formatMessage({id: 'splash.projectsByScratchersFollowing'})}
key="custom_projects_by_following"> key="custom_projects_by_following">
<Carousel items={this.state.featuredCustom.custom_projects_by_following} /> <Carousel items={this.state.featuredCustom.custom_projects_by_following} />
</Box> </Box>
); );
@ -271,7 +271,7 @@ var Splash = injectIntl(React.createClass({
rows.push( rows.push(
<Box title={formatMessage({id: 'splash.projectsLovedByScratchersFollowing'})} <Box title={formatMessage({id: 'splash.projectsLovedByScratchersFollowing'})}
key="custom_projects_loved_by_following"> key="custom_projects_loved_by_following">
<Carousel items={this.state.featuredCustom.custom_projects_loved_by_following} /> <Carousel items={this.state.featuredCustom.custom_projects_loved_by_following} />
</Box> </Box>
); );
@ -283,7 +283,7 @@ var Splash = injectIntl(React.createClass({
rows.push( rows.push(
<Box title={formatMessage({id:'splash.projectsInStudiosFollowing'})} <Box title={formatMessage({id:'splash.projectsInStudiosFollowing'})}
key="custom_projects_in_studios_following"> key="custom_projects_in_studios_following">
<Carousel items={this.state.featuredCustom.custom_projects_in_studios_following} /> <Carousel items={this.state.featuredCustom.custom_projects_in_studios_following} />
</Box> </Box>
); );

View file

@ -1,6 +1,6 @@
{ {
"wedo2.intro": "The LEGO® Education WeDo 2.0 is an introductory invention kit you can use to build your own interactive machines. You can snap together Scratch programming blocks to interact with your LEGO WeDo creations and add animations on the screen.", "wedo2.intro": "The LEGO® Education WeDo 2.0 is an introductory invention kit you can use to build your own interactive machines. You can snap together Scratch programming blocks to interact with your LEGO WeDo creations and add animations on the screen.",
"wedo2.requirement": "The LEGO WeDo 2.0 extension is currently only available for Mac OSX. We plan to release a Windows version later in 2016.", "wedo2.requirement": "The LEGO WeDo 2.0 extension is available for Mac OSX and Windows 10+",
"wedo2.getStarted": "Getting Started with LEGO WeDo 2.0", "wedo2.getStarted": "Getting Started with LEGO WeDo 2.0",
"wedo2.installTitle": "1. Install Device Manager", "wedo2.installTitle": "1. Install Device Manager",
"wedo2.installText": "The Device Manager lets you connect WeDo 2.0 to Scratch using Bluetooth <a href=\"https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1084869222&mt=12\">Download Here</a>", "wedo2.installText": "The Device Manager lets you connect WeDo 2.0 to Scratch using Bluetooth <a href=\"https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1084869222&mt=12\">Download Here</a>",

View file

@ -1,4 +1,4 @@
{ {
"2ec20d41b181e1a41c071e13f414a74d": "test.id1", "2ec20d41b181e1a41c071e13f414a74d": ["test.id1"],
"37ba6d5ef524504215f478912155f9ba": "test.id2" "37ba6d5ef524504215f478912155f9ba": ["test.id2"]
} }

View file

@ -0,0 +1,23 @@
var merge = require('lodash.merge');
var tap = require('tap');
var buildLocales = require('../../bin/lib/locale-compare');
tap.test('buildIcuMap', function (t) {
var ids1 = {
'first.test1' : 'We know where we\'re going, but we don\'t know where we\'ve been',
'first.test2' : 'You may find yourself living in a shotgun shack'
};
var ids2 = {
'second.test1' : 'We know where we\'re going, but we don\'t know where we\'ve been',
'second.test2' : 'Gadji beri bimba clandridi'
};
var testicuMap = buildLocales.icuToIdMap('first', ids1);
testicuMap = merge(testicuMap, buildLocales.icuToIdMap('second', ids2), buildLocales.customMerge);
t.ok(testicuMap['We know where we\'re going, but we don\'t know where we\'ve been'].length === 2);
t.ok(testicuMap['You may find yourself living in a shotgun shack'].length === 1);
t.ok(testicuMap['Gadji beri bimba clandridi'].length === 1);
t.end();
});

View file

@ -0,0 +1,25 @@
var tap = require('tap');
var buildLocales = require('../../bin/lib/locale-compare');
tap.test('buildLocalesMergeDupStrings', function (t) {
var existingTranslations = {
'test.test1': 'It\'s like raaayaaain, on your wedding day',
'test.test2': 'Free to flyyy, when you already paid',
'test.test4': 'Free to flyyy, when you already paid'
};
var newTranslations = {
'Isn\'t it ironic? No.': 'Es irónico? No.'
};
var md5map = {
'c21ce5ceefe167028182032d4255a384': ['test.test1'],
'9c40648034e467e16f8d6ae24bd610ab': ['test.test2', 'test.test4'],
'6885a345adafb3a9dd43d9f549430c88': ['test.test3', 'test.test5']
};
var mergedTranslations = buildLocales.mergeNewTranslations(existingTranslations, newTranslations, {}, md5map);
t.ok(mergedTranslations['test.test2'] !== undefined);
t.ok(mergedTranslations['test.test3'] !== undefined);
t.ok(mergedTranslations['test.test5'] !== undefined);
t.end();
});

View file

@ -11,9 +11,9 @@ tap.test('buildLocalesMergeTranslations', function (t) {
'Isn\'t it ironic? No.': 'Es irónico? No.' 'Isn\'t it ironic? No.': 'Es irónico? No.'
}; };
var md5map = { var md5map = {
'c21ce5ceefe167028182032d4255a384': 'test.test1', 'c21ce5ceefe167028182032d4255a384': ['test.test1'],
'9c40648034e467e16f8d6ae24bd610ab': 'test.test2', '9c40648034e467e16f8d6ae24bd610ab': ['test.test2'],
'6885a345adafb3a9dd43d9f549430c88': 'test.test3' '6885a345adafb3a9dd43d9f549430c88': ['test.test3']
}; };
var mergedTranslations = buildLocales.mergeNewTranslations(existingTranslations, newTranslations, {}, md5map); var mergedTranslations = buildLocales.mergeNewTranslations(existingTranslations, newTranslations, {}, md5map);