mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 09:35:56 -05:00
Merge pull request #961 from chrisgarrity/gh940-missing-i18n
[Master] Hotfix - update build-locales script
This commit is contained in:
commit
67d62cc4c1
10 changed files with 89 additions and 22 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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?'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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>",
|
||||||
|
|
4
test/fixtures/test_es_md5map.json
vendored
4
test/fixtures/test_es_md5map.json
vendored
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"2ec20d41b181e1a41c071e13f414a74d": "test.id1",
|
"2ec20d41b181e1a41c071e13f414a74d": ["test.id1"],
|
||||||
"37ba6d5ef524504215f478912155f9ba": "test.id2"
|
"37ba6d5ef524504215f478912155f9ba": ["test.id2"]
|
||||||
}
|
}
|
||||||
|
|
23
test/functional/build_locales_icuMap.js
Normal file
23
test/functional/build_locales_icuMap.js
Normal 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();
|
||||||
|
});
|
25
test/functional/build_locales_mergeDupStrings.js
Normal file
25
test/functional/build_locales_mergeDupStrings.js
Normal 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();
|
||||||
|
});
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue