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

cordova-plugin-localization-strings

Package Overview
Dependencies
Maintainers
2
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cordova-plugin-localization-strings - npm Package Compare versions

Comparing version 3.2.1 to 4.0.0

79

package.json
{
"name": "cordova-plugin-localization-strings",
"version": "3.2.1",
"description": "Cordova Plugin for handling localization strings on InfoPlist.strings and Localizable.strings on iOS, strings.xml on Android",
"repository": {
"type": "git",
"url": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git"
},
"engines": [
{
"name": "cordova",
"version": ">=6.0.0"
}
],
"keywords": [
"ecosystem:cordova",
"cordova-android",
"cordova-ios",
"i18n",
"internationalization",
"l10n",
"localization",
"strings.xml",
"InfoPlist.strings",
"Localizable.strings"
],
"dependencies": {
"fs-extra": "^1.0.0",
"iconv-lite": "^0.4.15",
"lodash": "^4.17.2",
"xcode": "^0.9.0",
"xml-writer": "^1.6.0",
"xml2js": "^0.4.17",
"xmldom": "^0.1.27",
"path": "^0.12.7",
"glob": "^7.1.3"
},
"devDependencies": {},
"license": "MIT",
"bugs": {
"url": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git/issues"
},
"homepage": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git"
"name": "cordova-plugin-localization-strings",
"version": "4.0.0",
"description": "Cordova Plugin for handling localization strings on InfoPlist.strings and Localizable.strings on iOS, strings.xml on Android",
"keywords": [
"ecosystem:cordova",
"cordova-android",
"cordova-ios",
"i18n",
"internationalization",
"l10n",
"localization",
"strings.xml",
"InfoPlist.strings",
"Localizable.strings"
],
"homepage": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git",
"bugs": {
"url": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/kelvinhokk/cordova-plugin-localization-strings.git"
},
"license": "MIT",
"dependencies": {
"glob": "^7.2.0",
"mkdirp": "^1.0.4",
"underscore": "^1.13.2",
"xcode": "^3.0.1",
"xml2js": "^0.4.23"
},
"engines": [
{
"name": "cordova",
"version": ">=6.0.0"
}
]
}

@@ -7,10 +7,7 @@ # Cordova Localization String Plugin

## How to Use
Install the plugin by fetching the dependencies
$ cordova plugin add cordova-plugin-localization-strings --save

@@ -29,28 +26,27 @@ Modify your project root to have the following structure:

|__ ja.json
```
A JSON file may look like this (Note: Breaking change from 1.0.0 onwards - new JSON format).
A JSON file may look like this (Note: Breaking change from 1.0.0 onwards - new JSON format).
```json
{
"config_ios" : {
"NSCameraUsageDescription": "Take pictures",
"CFBundleDisplayName": "Some App Name",
"CFBundleName": "Some App Name"
},
"config_android" : {
"app_name": "Some App Name"
},
"app" : {
"HAVE_MAIL_TITLE": "You have mail.",
"HAVE_MAIL_MSG": "%1$@ has you a message titled \\\"%2$@\\\""
}
"config_ios": {
"NSCameraUsageDescription": "Take pictures",
"CFBundleDisplayName": "Some App Name",
"CFBundleName": "Some App Name"
},
"config_android": {
"app_name": "Some App Name"
},
"app": {
"HAVE_MAIL_TITLE": "You have mail.",
"HAVE_MAIL_MSG": "%1$@ has you a message titled \\\"%2$@\\\""
}
}
```
By default, the language for the Localizable.strings, InfoPlist.strings or strings.xml is taken from the filename.
```
By default, the language for the Localizable.strings, InfoPlist.strings or strings.xml is taken from the filename.
For example, if the filename is es.json, the language is hence "es", and the plugin will create "/Resources/es.lproj/Localizable.strings" or "/values-es/strings.xml".
For example, if the filename is es.json, the language is hence "es", and the plugin will create "/Resources/es.lproj/Localizable.strings" or "/values-es/strings.xml".
Install iOS or Android platform

@@ -60,6 +56,6 @@

cordova platform add android
Run the code
cordova prepare ios
cordova prepare ios

@@ -69,58 +65,61 @@ #### Platform Specific Localizations

There are some platform specific localizations which differ for Android and iOS, for example for Android:
- zh-rCN
- zh-rHK
- zh-rTW
- zh-rCN
- zh-rHK
- zh-rTW
and for iOS:
- zh-Hans
- zh-Hans-CN
- zh-Hant
- zh-Hant-TW
In this case, you can use the locale in the json file to specify the platform localizations as in the following examples.
- zh-Hans
- zh-Hans-CN
- zh-Hant
- zh-Hant-TW
N.B. The "locale" key is optional (if platform localization is not required).
In this case, you can use the locale in the json file to specify the platform localizations as in the following examples.
N.B. The "locale" key is optional (if platform localization is not required).
zh-Hans.json
```json
{
"locale": {
"ios": ["zh-Hans"],
"android": ["zh-rCN"]
},
"config_ios": {
"NSCameraUsageDescription": "扫描二维码",
"CFBundleDisplayName": "应用程序名称",
"CFBundleName": "应用程序名称"
},
"config_android": {
"app_name": "应用程序名称"
},
"app": {
"HAVE_MAIL_TITLE": "你收到了邮件",
"HAVE_MAIL_MSG": "%1$@给您发送了封邮件,标题为\\\"%2$@\\\""
}
"locale": {
"ios": ["zh-Hans"],
"android": ["zh-rCN"]
},
"config_ios": {
"NSCameraUsageDescription": "扫描二维码",
"CFBundleDisplayName": "应用程序名称",
"CFBundleName": "应用程序名称"
},
"config_android": {
"app_name": "应用程序名称"
},
"app": {
"HAVE_MAIL_TITLE": "你收到了邮件",
"HAVE_MAIL_MSG": "%1$@给您发送了封邮件,标题为\\\"%2$@\\\""
}
}
```
zh-Hant.json
```json
{
"locale": {
"ios": ["zh-Hant"],
"android": ["zh-rTW", "zh-rHK"]
},
"config_ios": {
"NSCameraUsageDescription": "掃描二維碼",
"CFBundleDisplayName": "應用程序名稱",
"CFBundleName": "應用程序名稱"
},
"config_android": {
"app_name": "應用程序名稱"
},
"app": {
"HAVE_MAIL_TITLE": "你收到了郵件",
"HAVE_MAIL_MSG": "%1$@給您發送了封郵件,標題為\\\"%2$@\\\""
}
"locale": {
"ios": ["zh-Hant"],
"android": ["zh-rTW", "zh-rHK"]
},
"config_ios": {
"NSCameraUsageDescription": "掃描二維碼",
"CFBundleDisplayName": "應用程序名稱",
"CFBundleName": "應用程序名稱"
},
"config_android": {
"app_name": "應用程序名稱"
},
"app": {
"HAVE_MAIL_TITLE": "你收到了郵件",
"HAVE_MAIL_MSG": "%1$@給您發送了封郵件,標題為\\\"%2$@\\\""
}
}

@@ -131,3 +130,3 @@ ```

This plugin relies on node-xcode >= 0.9.0, node >= 5.0.0, cordova >= 6.0.0.
This plugin relies on node >= 5.0.0, cordova >= 6.0.0.

@@ -138,3 +137,3 @@ Do remember to install the other dependencies via the --fetch when installing the plugin.

Typically in a Cordova application, localization is performed on the javascript layer. There are several libraries to do help do so like angular-translate on ionic 1 and ngx-translate on ionic 2, with the help of plugins like cordova-plugin-globalization to retrieved the locale or preferred language natively.
Typically, in a Cordova application, localization is performed on the javascript layer. There are several libraries to help do so like angular-translate on ionic 1 and ngx-translate on ionic 2, with the help of plugins like cordova-plugin-globalization to retrieve the locale or preferred language natively.

@@ -145,19 +144,19 @@ This plugin helps in native localization in the following use cases:

The plugin will help to localize your app name if you require it to be named differently in different languages. Use the following json file format.
The plugin will help to localize your app name if you require it to be named differently in different languages. Use the following json file format.
```json
{
"config_ios" : {
"CFBundleDisplayName": "Some App Name",
"CFBundleName": "Some App Name"
},
"config_android" : {
"app_name": "Some App Name"
}
"config_ios": {
"CFBundleDisplayName": "Some App Name",
"CFBundleName": "Some App Name"
},
"config_android": {
"app_name": "Some App Name"
}
}
```
```
### Localizing iOS Permissions
This plugin will help in localize the iOS permission descriptions, for example NSCameraUsageDescription. A full list of iOS permissions and other infoPlist strings that can be found here. (https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html "CocoaKeys")
This plugin will help in localize the iOS permission descriptions, for example NSCameraUsageDescription. A full list of iOS permissions and other infoPlist strings that can be found here. (https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html "CocoaKeys")

@@ -168,16 +167,16 @@ Example usage:

{
"config_ios" : {
"NSCameraUsageDescription": "Take pictures",
"NSLocationUsageDescription": "Need Location for Some Purpose",
}
"config_ios": {
"NSCameraUsageDescription": "Take pictures",
"NSLocationUsageDescription": "Need Location for Some Purpose"
}
}
```
### Push notifications messages
### Push notifications messages
Typically, there are 2 main ways push notifications can be localised:
* your app saves your user's selected language on the server, and pushes a localised string in the push notification to your user.
* your server pushes a key to the phone, and the app displays a localised version based on the key in the localization bundle, as determined from the user's phone OS's languauge.
- your app saves your user's selected language on the server, and pushes a localised string in the push notification to your user.
- your server pushes a key to the phone, and the app displays a localised version based on the key in the localization bundle, as determined from the user's phone OS's language.
This plugin helps in the latter approach.

@@ -187,6 +186,5 @@

* Storing Localized Content in Your App Bundle (https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW9)
* Formatting strings (https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling)
- Storing Localized Content in Your App Bundle (https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW9)
- Formatting strings (https://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling)
Example usage:

@@ -196,11 +194,11 @@

{
"app" : {
"HAVE_MAIL_TITLE": "You have mail.",
"HAVE_INVITE_MSG": "%1$@ has invited you to game room %2$@"
}
"app": {
"HAVE_MAIL_TITLE": "You have mail.",
"HAVE_INVITE_MSG": "%1$@ has invited you to game room %2$@"
}
}
```
The plugin will automatically generate Localizable.strings file using the following entry on iOS:
```

@@ -212,2 +210,3 @@ "HAVE_MAIL_TITLE" = "You have mail.";

And on Android, the respective locale's strings.xml:
```xml

@@ -223,10 +222,10 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

The plugin reads the assumed directory structure. The plugin reads from all the fields in config_ios and writes into the InfoPlist.strings, which will be placed in the respective locale.lproj directory. The rest of the strings in "app" will be placed in the Localizable.strings file and placed in the locale directory.
The plugin reads the assumed directory structure. The plugin reads from all the fields in config_ios and writes into the InfoPlist.strings, which will be placed in the respective locale.lproj directory. The rest of the strings in "app" will be placed in the Localizable.strings file and placed in the locale directory.
## Details (Android)
The plugin reads the assumed directory structure, the plugin will combine all properties in "config_android" and "app", and inserted into the strings.xml of the locale's /res/val-locale/strings.xml
The plugin reads the assumed directory structure, the plugin will combine all properties in "config_android" and "app", and inserted into the strings.xml of the locale's /res/val-locale/strings.xml
## Override platform specific translations:
## Override platform specific translations:
```json

@@ -248,2 +247,3 @@ {

```
(if `app_ios` or `app_android` are detected they will be used and override keys from `app`)

@@ -1,3 +0,6 @@

var fs = require('fs-extra');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var mkdirp = require('mkdirp');
var _ = require('underscore');
var xml2js = require('xml2js');

@@ -18,3 +21,3 @@

languages.forEach(function (lang) {
//read the json file
// read the json file
var langJson = require(lang.path);

@@ -24,4 +27,4 @@

var localeLangs = [];
if (_.has(langJson, "locale") && _.has(langJson.locale, "android")) {
//iterate the locales to to be iterated.
if (_.has(langJson, 'locale') && _.has(langJson.locale, 'android')) {
// iterate the locales
_.forEach(langJson.locale.android, function (aLocale) {

@@ -42,4 +45,4 @@ localeLangs.push(aLocale);

stringXmlJson = {
"resources": {
"string": []
resources: {
string: []
}

@@ -49,25 +52,29 @@ };

} else {
//lets read from strings.xml into json
fs.readFile(stringXmlFilePath, {encoding: 'utf8'}, function (err, data) {
if (err) {
throw err;
}
promisesToRun.push(
new Promise(function (resolve, reject) {
// lets read from strings.xml into json
fs.readFile(stringXmlFilePath, function (err, data) {
if (err) {
return reject(err);
}
parser.parseString(data, function (err, result) {
if (err) {
throw err;
}
parser.parseString(data, function (err, result) {
if (err) {
return reject(err);
}
stringXmlJson = result;
stringXmlJson = result;
// initialize xmlJson to have strings
if (!_.has(stringXmlJson, "resources") || !_.has(stringXmlJson.resources, "string")) {
stringXmlJson.resources = {
"string": []
};
}
// initialize xmlJson to have strings
if (!_.has(stringXmlJson, 'resources') || !_.has(stringXmlJson.resources, 'string')) {
stringXmlJson.resources = {
string: []
};
}
promisesToRun.push(processResult(context, localeLang, langJson, stringXmlJson));
});
});
processResult(context, localeLang, langJson, stringXmlJson).then(resolve, reject);
});
});
})
);
}

@@ -81,23 +88,15 @@ });

function getTranslationPath (config, name) {
var value = config.match(new RegExp('name="' + name + '" value="(.*?)"', "i"))
if(value && value[1]) {
return value[1];
} else {
return null;
}
function getTranslationPath(config, name) {
var matches = config.match(new RegExp('name="' + name + '" value="(.*?)"', 'i'));
return (matches && matches[1]) || null;
}
function getDefaultPath(context){
function getDefaultPath(context) {
var configNodes = context.opts.plugin.pluginInfo._et._root._children;
var defaultTranslationPath = '';
for (var node in configNodes) {
if (configNodes[node].attrib.name == 'TRANSLATION_PATH') {
defaultTranslationPath = configNodes[node].attrib.default;
if (configNodes[node].attrib.name === 'TRANSLATION_PATH') {
return configNodes[node].attrib.default;
}
}
return defaultTranslationPath;
return '';
}

@@ -108,86 +107,52 @@

var path = require('path');
var glob = require('glob');
var providedTranslationPathPattern;
var providedTranslationPathRegex;
var config = fs.readFileSync("config.xml").toString();
var PATH = getTranslationPath(config, "TRANSLATION_PATH");
var config = fs.readFileSync('config.xml').toString();
var PATH = getTranslationPath(config, 'TRANSLATION_PATH');
if(PATH == null){
if (PATH == null) {
PATH = getDefaultPath(context);
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
}
if(PATH != null){
if(/^\s*$/.test(PATH)){
if (PATH != null) {
if (/^\s*$/.test(PATH)) {
providedTranslationPathPattern = getDefaultPath(context);
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
} else {
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
}
else {
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
}
}
return new Promise(function(resolve, reject) {
glob(providedTranslationPathPattern, function(error, langFiles) {
if (error) {
reject(error);
}
langFiles.forEach(function(langFile) {
var matches = langFile.match(providedTranslationPathRegex);
if (matches) {
targetLangArr.push({
lang: matches[1],
path: path.join(context.opts.projectRoot, langFile)
return new Promise(function (resolve, reject) {
glob(providedTranslationPathPattern, function (error, langFiles) {
if (error) {
reject(error);
}
langFiles.forEach(function (langFile) {
var matches = langFile.match(providedTranslationPathRegex);
if (matches) {
targetLangArr.push({
lang: matches[1],
path: path.join(context.opts.projectRoot, langFile)
});
}
});
}
resolve(targetLangArr);
});
resolve(targetLangArr);
})
});
}
function getLocalizationDir(context, lang) {
var path = require('path');
var langDir;
switch (lang) {
case "en":
langDir = path.normalize(path.join(getResPath(context), 'values'));
break;
default:
langDir = path.normalize(path.join(getResPath(context), 'values-' + lang));
break;
}
return langDir;
}
function getLocalStringXmlPath(context, lang) {
var path = require('path');
var filePath;
switch (lang) {
case "en":
filePath = path.normalize(path.join(getResPath(context), 'values/strings.xml'));
break;
default:
filePath = path.normalize(path.join(getResPath(context), 'values-' + lang + '/', 'strings.xml'));
break;
}
return filePath;
var resPath = getResPath(context);
return path.normalize(path.join(resPath, 'values' + (lang !== 'en' ? '-' + lang : ''), 'strings.xml'));
}
function getResPath(context) {
var path = require('path');
var locations = context.requireCordovaModule('cordova-lib/src/platforms/platforms').getPlatformApi('android').locations;
if (locations && locations.res) {
return locations.res;
}
return path.join(context.opts.projectRoot, 'platforms/android/res');
return (locations && locations.res) || path.join(context.opts.projectRoot, 'platforms/android/res');
}
// process the modified xml and put write to file
// process the modified xml and write to file
function processResult(context, lang, langJson, stringXmlJson) {

@@ -197,18 +162,18 @@ var mapObj = {};

_.forEach(stringXmlJson.resources.string, function (val) {
if (_.has(val, "$") && _.has(val["$"], "name")) {
mapObj[val["$"].name] = val;
if (_.has(val, '$') && _.has(val['$'], 'name')) {
mapObj[val['$'].name] = val;
}
});
var langJsonToProcess = _.assignIn(langJson.config_android, langJson.app, langJson.app_android);
var langJsonToProcess = _.extend(langJson.config_android, langJson.app, langJson.app_android);
//now iterate through langJsonToProcess
// now iterate through langJsonToProcess
_.forEach(langJsonToProcess, function (val, key) {
// positional string format is in Mac OS X format. change to android format
val = val.replace(/\$@/gi, "$s");
val = val.replace(/\'/gi, "\\'");
// positional string format is in Mac OS X format. change to android format
val = val.replace(/\$@/gi, '$s');
val = val.replace(/'/gi, "\\'");
if (_.has(mapObj, key)) {
// mapObj contains key. replace key
mapObj[key]["_"] = val;
mapObj[key]['_'] = val;
} else {

@@ -218,3 +183,3 @@ // add by inserting

_: val,
'$': {name: key}
$: { name: key }
});

@@ -224,23 +189,11 @@ }

//save to disk
var langDir = getLocalizationDir(context, lang);
// save to disk
var filePath = getLocalStringXmlPath(context, lang);
var langDir = path.dirname(filePath);
return new Promise(function(resolve, reject) {
fs.ensureDir(langDir, function (error) {
if (error) {
reject(error);
}
return mkdirp(langDir).then(function () {
fs.writeFileSync(filePath, buildXML(stringXmlJson));
console.log('Localization saved:', filePath);
});
fs.writeFile(filePath, buildXML(stringXmlJson), {encoding: 'utf8'}, function (error) {
if (error) {
reject(error);
}
console.log('Saved:' + filePath);
resolve();
});
});
})
function buildXML(obj) {

@@ -247,0 +200,0 @@ var builder = new xml2js.Builder();

@@ -1,20 +0,15 @@

var fs = require('fs-extra');
var _ = require('lodash');
var iconv = require('iconv-lite');
var xmldom = require('xmldom');
var fs = require('fs');
var path = require('path');
var glob = require('glob');
var mkdirp = require('mkdirp');
var _ = require('underscore');
var xcode = require('xcode');
var iosProjFolder;
var iosPbxProjPath;
var getValue = function(configDoc, name) {
var name = configDoc.getElementsByTagName(name)[0];
return name.textContent
}
function jsonToDotStrings(jsonObj){
var returnString = "";
_.forEach(jsonObj, function(val, key){
returnString += '"'+key+'" = "' + val +'";\n';
function jsonToDotStrings(jsonObj) {
var returnString = '';
_.forEach(jsonObj, function (val, key) {
returnString += '"' + key + '" = "' + val + '";\n';
});

@@ -24,10 +19,13 @@ return returnString;

function initIosDir(){
function getProjectName() {
var config = fs.readFileSync('config.xml').toString();
var matches = config.match(new RegExp('<name>(.*?)</name>', 'i'));
return (matches && matches[1]) || null;
}
function initIosDir() {
if (!iosProjFolder || !iosPbxProjPath) {
var config = fs.readFileSync("config.xml").toString();
var configDoc = (new xmldom.DOMParser()).parseFromString(config, 'application/xml');
var name = getValue(configDoc, "name");
iosProjFolder = "platforms/ios/" + name;
iosPbxProjPath = "platforms/ios/" + name + ".xcodeproj/project.pbxproj";
var projectName = getProjectName();
iosProjFolder = 'platforms/ios/' + projectName;
iosPbxProjPath = 'platforms/ios/' + projectName + '.xcodeproj/project.pbxproj';
}

@@ -47,17 +45,10 @@ }

function writeStringFile(plistStringJsonObj, lang, fileName) {
var lProjPath = getTargetIosDir() + "/Resources/" + lang + ".lproj";
fs.ensureDir(lProjPath, function (err) {
if (!err) {
var stringToWrite = jsonToDotStrings(plistStringJsonObj);
var buffer = iconv.encode(stringToWrite, 'utf8');
fs.open(lProjPath + "/" + fileName, 'w', function(err, fd) {
if(err) throw err;
fs.writeFileSync(fd, buffer);
});
}
var lProjPath = getTargetIosDir() + '/Resources/' + lang + '.lproj';
mkdirp(lProjPath).then(function () {
var stringToWrite = jsonToDotStrings(plistStringJsonObj);
fs.writeFileSync(path.join(lProjPath, fileName), stringToWrite);
});
}
function writeLocalisationFieldsToXcodeProj(filePaths, groupname, proj) {
function writeLocalisationFieldsToXcodeProj(filePaths, groupName, proj) {
var fileRefSection = proj.pbxFileReferenceSection();

@@ -67,8 +58,6 @@ var fileRefValues = _.values(fileRefSection);

if (filePaths.length > 0) {
// var groupKey;
var groupKey = proj.findPBXVariantGroupKey({name: groupname});
var groupKey = proj.findPBXVariantGroupKey({ name: groupName });
if (!groupKey) {
// findPBXVariantGroupKey with name InfoPlist.strings not found. creating new group
var localizableStringVarGroup = proj.addLocalizationVariantGroup(groupname);
// findPBXVariantGroupKey with name InfoPlist.strings not found. creating new group
var localizableStringVarGroup = proj.addLocalizationVariantGroup(groupName);
groupKey = localizableStringVarGroup.fileRef;

@@ -78,8 +67,8 @@ }

filePaths.forEach(function (path) {
var results = _.find(fileRefValues, function(o){
return (_.isObject(o) && _.has(o, "path") && o.path.replace(/['"]+/g, '') == path)
var results = _.find(fileRefValues, function (o) {
return _.isObject(o) && _.has(o, 'path') && o.path.replace(/['"]+/g, '') === path;
});
if (_.isUndefined(results)) {
//not found in pbxFileReference yet
proj.addResourceFile("Resources/" + path, {variantGroup: true}, groupKey);
// not found in pbxFileReference yet
proj.addResourceFile('Resources/' + path, { variantGroup: true }, groupKey);
}

@@ -89,153 +78,132 @@ });

}
module.exports = function(context) {
var xcode = require('xcode');
module.exports = function (context) {
var infoPlistPaths = [];
var localizableStringsPaths = [];
var infoPlistPaths = [];
return getTargetLang(context)
.then(function(languages) {
return getTargetLang(context).then(function (languages) {
languages.forEach(function (lang) {
// read the json file
var langJson = require(lang.path);
languages.forEach(function(lang){
// check the locales to write to
var localeLangs = [];
if (_.has(langJson, 'locale') && _.has(langJson.locale, 'ios')) {
// iterate the locales
_.forEach(langJson.locale.ios, function (aLocale) {
localeLangs.push(aLocale);
});
} else {
// use the default lang from the filename, for example "en" in en.json
localeLangs.push(lang.lang);
}
//read the json file
var langJson = require(lang.path);
// check the locales to write to
var localeLangs = [];
if (_.has(langJson, "locale") && _.has(langJson.locale, "ios")) {
//iterate the locales to to be iterated.
_.forEach(langJson.locale.ios, function(aLocale){
localeLangs.push(aLocale);
});
_.forEach(localeLangs, function (localeLang) {
if (_.has(langJson, 'config_ios')) {
// do processing for appname into plist
var plistString = langJson.config_ios;
if (!_.isEmpty(plistString)) {
writeStringFile(plistString, localeLang, 'InfoPlist.strings');
infoPlistPaths.push(localeLang + '.lproj/' + 'InfoPlist.strings');
}
}
else {
// use the default lang from the filename, for example "en" in en.json
localeLangs.push(lang.lang);
}
_.forEach(localeLangs, function(localeLang){
if (_.has(langJson, "config_ios")) {
//do processing for appname into plist
var plistString = langJson.config_ios;
if (!_.isEmpty(plistString)) {
writeStringFile(plistString, localeLang, "InfoPlist.strings");
infoPlistPaths.push(localeLang + ".lproj/" + "InfoPlist.strings");
}
// remove APP_NAME and write to Localizable.strings
if (_.has(langJson, 'app')) {
// do processing for appname into plist
var localizableStringsJson = langJson.app;
// ios specific strings
if (_.has(langJson, 'app_ios')) {
Object.assign(localizableStringsJson, langJson.app_ios);
}
//remove APP_NAME and write to Localizable.strings
if (_.has(langJson, "app")) {
//do processing for appname into plist
var localizableStringsJson = langJson.app;
//ios specific strings
if (_.has(langJson, "app_ios")){
Object.assign(localizableStringsJson, langJson.app_ios);
}
if (!_.isEmpty(localizableStringsJson)) {
writeStringFile(localizableStringsJson, localeLang, "Localizable.strings");
localizableStringsPaths.push(localeLang + ".lproj/" + "Localizable.strings");
}
if (!_.isEmpty(localizableStringsJson)) {
writeStringFile(localizableStringsJson, localeLang, 'Localizable.strings');
localizableStringsPaths.push(localeLang + '.lproj/' + 'Localizable.strings');
}
});
}
});
});
var proj = xcode.project(getXcodePbxProjPath());
var pbxProjPath = getXcodePbxProjPath();
var proj = xcode.project(pbxProjPath);
return new Promise(function (resolve, reject) {
proj.parse(function (error) {
if (error) {
return new Promise(function (resolve, reject) {
proj.parse(function (error) {
if (error) {
reject(error);
}
}
writeLocalisationFieldsToXcodeProj(localizableStringsPaths, 'Localizable.strings', proj);
writeLocalisationFieldsToXcodeProj(infoPlistPaths, 'InfoPlist.strings', proj);
writeLocalisationFieldsToXcodeProj(infoPlistPaths, 'InfoPlist.strings', proj);
writeLocalisationFieldsToXcodeProj(localizableStringsPaths, 'Localizable.strings', proj);
fs.writeFileSync(getXcodePbxProjPath(), proj.writeSync());
console.log('new pbx project written with localization groups');
var platformPath = path.join( context.opts.projectRoot, "platforms", "ios" );
var projectFileApi = require( path.join( platformPath, "/cordova/lib/projectFile.js" ) );
projectFileApi.purgeProjectFileCache( platformPath );
console.log(platformPath + ' purged from project cache');
resolve();
});
fs.writeFileSync(pbxProjPath, proj.writeSync());
console.log('Pbx project written with localization groups', _.map(languages, 'lang'));
var platformPath = path.join(context.opts.projectRoot, 'platforms', 'ios');
var projectFileApi = require(path.join(platformPath, '/cordova/lib/projectFile.js'));
projectFileApi.purgeProjectFileCache(platformPath);
resolve();
});
});
});
};
function getTranslationPath (config, name) {
var value = config.match(new RegExp('name="' + name + '" value="(.*?)"', "i"))
if(value && value[1]) {
return value[1];
} else {
return null;
}
function getTranslationPath(config, name) {
var matches = config.match(new RegExp('name="' + name + '" value="(.*?)"', 'i'));
return (matches && matches[1]) || null;
}
function getDefaultPath(context){
function getDefaultPath(context) {
var configNodes = context.opts.plugin.pluginInfo._et._root._children;
var defaultTranslationPath = '';
for (var node in configNodes) {
if (configNodes[node].attrib.name == 'TRANSLATION_PATH') {
defaultTranslationPath = configNodes[node].attrib.default;
if (configNodes[node].attrib.name === 'TRANSLATION_PATH') {
return configNodes[node].attrib.default;
}
}
return defaultTranslationPath;
return '';
}
function getTargetLang(context) {
var targetLangArr = [];
var path = require('path');
var glob = require('glob');
var providedTranslationPathPattern;
var providedTranslationPathRegex;
var config = fs.readFileSync("config.xml").toString();
var PATH = getTranslationPath(config, "TRANSLATION_PATH");
var config = fs.readFileSync('config.xml').toString();
var PATH = getTranslationPath(config, 'TRANSLATION_PATH');
if(PATH == null){
if (PATH == null) {
PATH = getDefaultPath(context);
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
}
if(PATH != null){
if(/^\s*$/.test(PATH)){
if (PATH != null) {
if (/^\s*$/.test(PATH)) {
providedTranslationPathPattern = getDefaultPath(context);
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
} else {
providedTranslationPathPattern = PATH + '*.json';
providedTranslationPathRegex = new RegExp(PATH + '(.*).json');
}
else {
providedTranslationPathPattern = PATH + "*.json";
providedTranslationPathRegex = new RegExp((PATH + "(.*).json"));
}
}
return new Promise(function (resolve, reject) {
glob(providedTranslationPathPattern, function(error, langFiles) {
if (error) {
reject(error);
}
langFiles.forEach(function(langFile) {
var matches = langFile.match(providedTranslationPathRegex);
if (matches) {
targetLangArr.push({
lang: matches[1],
path: path.join(context.opts.projectRoot, langFile)
glob(providedTranslationPathPattern, function (error, langFiles) {
if (error) {
reject(error);
}
langFiles.forEach(function (langFile) {
var matches = langFile.match(providedTranslationPathRegex);
if (matches) {
targetLangArr.push({
lang: matches[1],
path: path.join(context.opts.projectRoot, langFile)
});
}
});
}
resolve(targetLangArr);
});
resolve(targetLangArr);
});
});
}

@@ -0,5 +1,5 @@

var android_script = require('./create_android_strings');
var ios_script = require('./create_ios_strings');
var android_script = require('./create_android_strings');
module.exports = function(context) {
module.exports = function (context) {
var platforms = context.opts.platforms;

@@ -9,2 +9,6 @@

if (platforms.indexOf('android') >= 0) {
promises.push(android_script(context));
}
if (platforms.indexOf('ios') >= 0) {

@@ -14,7 +18,3 @@ promises.push(ios_script(context));

if (platforms.indexOf('android') >= 0) {
promises.push(android_script(context));
}
return Promise.all(promises);
};
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