mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-03-14 15:09:59 -04:00
Merge pull request #960 from chrisgarrity/gh940-missing-i18n
Fix gh-940: missing translations
This commit is contained in:
commit
4074b986c2
9 changed files with 88 additions and 21 deletions
|
@ -86,7 +86,7 @@ for (var v in routes) {
|
|||
if (typeof routes[v].redirect !== 'undefined') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
views.push(routes[v].name);
|
||||
try {
|
||||
var subdir = routes[v].view.split('/');
|
||||
|
@ -97,7 +97,8 @@ for (var v in routes) {
|
|||
en: 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) {
|
||||
if (err.code !== 'MODULE_NOT_FOUND') {
|
||||
throw err;
|
||||
|
|
|
@ -6,6 +6,7 @@ var crypto = require('crypto');
|
|||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var po2icu = require('po2icu');
|
||||
var isArray = require('lodash.isarray');
|
||||
|
||||
var Helpers = {};
|
||||
|
||||
|
@ -20,6 +21,21 @@ Helpers.getMD5 = function (string) {
|
|||
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.
|
||||
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) {
|
||||
var md5 = Helpers.getMD5(id);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var translationsByView = {};
|
||||
for (var id in translations) {
|
||||
var ids = id.split(separator); // [viewName, stringId]
|
||||
|
@ -132,7 +150,7 @@ Helpers.writeTranslationsToJS = function (outputDir, viewName, translationObject
|
|||
Helpers.idToICUMap = function (viewName, ids, separator) {
|
||||
var idsToICU = {};
|
||||
separator = separator || ':';
|
||||
|
||||
|
||||
for (var id in ids) {
|
||||
idsToICU[viewName + separator + id] = ids[id];
|
||||
}
|
||||
|
@ -146,7 +164,7 @@ Helpers.icuToIdMap = function (viewName, ids, separator) {
|
|||
separator = separator || ':';
|
||||
|
||||
for (var id in ids) {
|
||||
icuToIds[ids[id]] = viewName + separator + id;
|
||||
icuToIds[ids[id]] = [viewName + separator + id];
|
||||
}
|
||||
return icuToIds;
|
||||
};
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"keymirror": "0.1.1",
|
||||
"lodash.clone": "3.0.3",
|
||||
"lodash.defaultsdeep": "3.10.0",
|
||||
"lodash.isarray": "3.0.4",
|
||||
"lodash.merge": "3.3.2",
|
||||
"lodash.omit": "3.1.0",
|
||||
"lodash.range": "3.0.1",
|
||||
|
|
|
@ -11,8 +11,7 @@ require('./activity.scss');
|
|||
|
||||
var defaultMessages = defineMessages({
|
||||
whatsHappening: {
|
||||
id: 'general.whatsHappening',
|
||||
defaultMessage: 'What\'s Happening?'
|
||||
id: 'general.whatsHappening'
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -215,11 +215,11 @@ var Splash = injectIntl(React.createClass({
|
|||
<Box
|
||||
key="curator_top_projects"
|
||||
title={
|
||||
'Projects Curated by ' +
|
||||
formatMessage({id: 'splash.projectsCuratedBy'}) +
|
||||
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/">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.curator_top_projects} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -234,9 +234,9 @@ var Splash = injectIntl(React.createClass({
|
|||
title={
|
||||
formatMessage({id: 'splash.scratchDesignStudioTitle'})
|
||||
+ ' - ' + 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 + '/'}>
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredGlobal.scratch_design_studio} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -260,7 +260,7 @@ var Splash = injectIntl(React.createClass({
|
|||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.projectsByScratchersFollowing'})}
|
||||
key="custom_projects_by_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_by_following} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -271,7 +271,7 @@ var Splash = injectIntl(React.createClass({
|
|||
rows.push(
|
||||
<Box title={formatMessage({id: 'splash.projectsLovedByScratchersFollowing'})}
|
||||
key="custom_projects_loved_by_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_loved_by_following} />
|
||||
</Box>
|
||||
);
|
||||
|
@ -283,7 +283,7 @@ var Splash = injectIntl(React.createClass({
|
|||
rows.push(
|
||||
<Box title={formatMessage({id:'splash.projectsInStudiosFollowing'})}
|
||||
key="custom_projects_in_studios_following">
|
||||
|
||||
|
||||
<Carousel items={this.state.featuredCustom.custom_projects_in_studios_following} />
|
||||
</Box>
|
||||
);
|
||||
|
|
4
test/fixtures/test_es_md5map.json
vendored
4
test/fixtures/test_es_md5map.json
vendored
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"2ec20d41b181e1a41c071e13f414a74d": "test.id1",
|
||||
"37ba6d5ef524504215f478912155f9ba": "test.id2"
|
||||
"2ec20d41b181e1a41c071e13f414a74d": ["test.id1"],
|
||||
"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.'
|
||||
};
|
||||
var md5map = {
|
||||
'c21ce5ceefe167028182032d4255a384': 'test.test1',
|
||||
'9c40648034e467e16f8d6ae24bd610ab': 'test.test2',
|
||||
'6885a345adafb3a9dd43d9f549430c88': 'test.test3'
|
||||
'c21ce5ceefe167028182032d4255a384': ['test.test1'],
|
||||
'9c40648034e467e16f8d6ae24bd610ab': ['test.test2'],
|
||||
'6885a345adafb3a9dd43d9f549430c88': ['test.test3']
|
||||
};
|
||||
|
||||
var mergedTranslations = buildLocales.mergeNewTranslations(existingTranslations, newTranslations, {}, md5map);
|
||||
|
|
Loading…
Reference in a new issue