forked from EVOgeek/Vmeda.Online
Merge pull request #3687 from crazyserver/MOBILE-4343
[4.3] Mobile 4343
This commit is contained in:
commit
d7a18dd36c
gulp
gulpfile.jsmoodle.config.jsonpackage.jsonscripts
create_langindex.shcreate_langindex_functions.shlang_functions.phplang_functions.shmoodle_to_json.phpupdate_lang.shupdate_lang_functions.shupdate_langpacks.sh
src
addons
block
activityresults
badges
blogmenu
blogrecent
blogtags
calendarmonth
calendarupcoming
comments
completionstatus
glossaryrandom
learningplans
newsitems
onlineusers
privatefiles
recentactivity
rssclient
selfcompletion
tags
blog
competency
coursecompletion
mod
choice
folder
imscp
lesson
lti
page
survey
url
privatefiles
assets
core/features
134
gulp/task-override-lang.js
Normal file
134
gulp/task-override-lang.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
const gulp = require('gulp');
|
||||||
|
const slash = require('gulp-slash');
|
||||||
|
const through = require('through');
|
||||||
|
const bufferFrom = require('buffer-from');
|
||||||
|
const pathLib = require('path');
|
||||||
|
const { readFileSync } = require('fs');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the English generated lang file (src/assets/lang/en.json) to override strings in features lang.json files.
|
||||||
|
*/
|
||||||
|
class OverrideLangTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the task.
|
||||||
|
*
|
||||||
|
* @param done Function to call when done.
|
||||||
|
*/
|
||||||
|
run(done) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const path = pathLib.join('./src/assets/lang', 'en.json');
|
||||||
|
const data = JSON.parse(readFileSync(path));
|
||||||
|
|
||||||
|
const files = {};
|
||||||
|
|
||||||
|
for (const key in data) {
|
||||||
|
let filePath = './src';
|
||||||
|
|
||||||
|
const exp = key.split('.');
|
||||||
|
|
||||||
|
|
||||||
|
const type = exp.shift();
|
||||||
|
let component = 'moodle';
|
||||||
|
let plainid = exp.shift();
|
||||||
|
|
||||||
|
if (exp.length > 0) {
|
||||||
|
component = plainid;
|
||||||
|
plainid = exp.join('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const component_slashes = component.replace('_', '/');
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'core':
|
||||||
|
if (component == 'moodle') {
|
||||||
|
filePath = pathLib.join(filePath, 'core/lang.json');
|
||||||
|
} else {
|
||||||
|
filePath = pathLib.join(filePath, `/core/features/${component_slashes}/lang.json`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'addon':
|
||||||
|
filePath = pathLib.join(filePath, `/addons/${component_slashes}/lang.json`);
|
||||||
|
break;
|
||||||
|
case 'assets':
|
||||||
|
filePath = pathLib.join(filePath, `/${type}/${component}.json`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
filePath = pathLib.join(filePath, `/${type}/lang.json`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
filePath = pathLib.resolve(filePath);
|
||||||
|
|
||||||
|
if (files[filePath] === undefined) {
|
||||||
|
files[filePath] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
files[filePath][plainid] = data[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const paths = Object.keys(files);
|
||||||
|
gulp.src(paths, { allowEmpty: true })
|
||||||
|
.pipe(slash())
|
||||||
|
.pipe(through(function(destFile) {
|
||||||
|
const oldContents = self.readFile(destFile);
|
||||||
|
destFile.contents = self.jsonFile(oldContents, files[destFile.path]);
|
||||||
|
|
||||||
|
this.emit('data', destFile);
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest((data) => data.base, { overwrite: true}))
|
||||||
|
.on('end', done);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads file.
|
||||||
|
*
|
||||||
|
* @param file File treated.
|
||||||
|
*/
|
||||||
|
readFile(file) {
|
||||||
|
if (file.isNull() || file.isStream()) {
|
||||||
|
return; // ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.parse(file.contents.toString());
|
||||||
|
} catch (err) {
|
||||||
|
console.log('Error parsing JSON: ' + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the stringified json.
|
||||||
|
*
|
||||||
|
* @param oldContents File old data.
|
||||||
|
* @param data File data.
|
||||||
|
* @return Buffer with the treated data.
|
||||||
|
*/
|
||||||
|
jsonFile(oldContents, data) {
|
||||||
|
data = Object.assign(oldContents, data);
|
||||||
|
|
||||||
|
const fileContents = {};
|
||||||
|
// Force ordering by string key.
|
||||||
|
Object.keys(data).sort().forEach((key) => {
|
||||||
|
fileContents[key] = data[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
return bufferFrom(JSON.stringify(fileContents, null, 4) + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = OverrideLangTask;
|
@ -16,6 +16,7 @@ const BuildLangTask = require('./gulp/task-build-lang');
|
|||||||
const BuildBehatPluginTask = require('./gulp/task-build-behat-plugin');
|
const BuildBehatPluginTask = require('./gulp/task-build-behat-plugin');
|
||||||
const BuildEnvTask = require('./gulp/task-build-env');
|
const BuildEnvTask = require('./gulp/task-build-env');
|
||||||
const PushTask = require('./gulp/task-push');
|
const PushTask = require('./gulp/task-push');
|
||||||
|
const OverrideLangTask = require('./gulp/task-override-lang');
|
||||||
const Utils = require('./gulp/utils');
|
const Utils = require('./gulp/utils');
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
|
|
||||||
@ -36,6 +37,11 @@ gulp.task('lang', (done) => {
|
|||||||
new BuildLangTask().run(paths.lang, done);
|
new BuildLangTask().run(paths.lang, done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Use the English generated lang file (src/assets/lang/en.json) to override strings in features lang.json files.
|
||||||
|
gulp.task('lang-override', (done) => {
|
||||||
|
new OverrideLangTask().run(done);
|
||||||
|
});
|
||||||
|
|
||||||
// Build an env file depending on the current environment.
|
// Build an env file depending on the current environment.
|
||||||
gulp.task('env', (done) => {
|
gulp.task('env', (done) => {
|
||||||
new BuildEnvTask().run(done);
|
new BuildEnvTask().run(done);
|
||||||
|
@ -10,18 +10,18 @@
|
|||||||
"default_lang": "en",
|
"default_lang": "en",
|
||||||
"languages": {
|
"languages": {
|
||||||
"af": "Afrikaans",
|
"af": "Afrikaans",
|
||||||
"ar": "عربي",
|
"ar": "العربية",
|
||||||
"az": "Azərbaycanca",
|
"az": "Azərbaycanca",
|
||||||
"bg": "Български",
|
"bg": "Български",
|
||||||
"ca": "Català",
|
"ca": "Català",
|
||||||
"cs": "Čeština",
|
"cs": "Čeština",
|
||||||
"da": "Dansk",
|
"da": "Dansk",
|
||||||
"de": "Deutsch",
|
"de": "Deutsch",
|
||||||
"de-du": "Deutsch - Du",
|
"de-du": "Deutsch (du)",
|
||||||
"el": "Ελληνικά",
|
"el": "Ελληνικά",
|
||||||
"en": "English",
|
"en": "English",
|
||||||
"en-us": "English - United States",
|
"en-us": "English (United States)",
|
||||||
"es": "Español",
|
"es": "Español - Internacional",
|
||||||
"es-mx": "Español - México",
|
"es-mx": "Español - México",
|
||||||
"eu": "Euskara",
|
"eu": "Euskara",
|
||||||
"fa": "فارسی",
|
"fa": "فارسی",
|
||||||
@ -31,10 +31,10 @@
|
|||||||
"he": "עברית",
|
"he": "עברית",
|
||||||
"hi": "हिंदी",
|
"hi": "हिंदी",
|
||||||
"hr": "Hrvatski",
|
"hr": "Hrvatski",
|
||||||
"hsb": "Hornjoserbsski",
|
"hsb": "Hornjoserbsce",
|
||||||
"hu": "magyar",
|
"hu": "magyar",
|
||||||
"hy": "Հայերեն",
|
"hy": "Հայերեն",
|
||||||
"id": "Indonesian",
|
"id": "Bahasa Indonesia",
|
||||||
"it": "Italiano",
|
"it": "Italiano",
|
||||||
"ja": "日本語",
|
"ja": "日本語",
|
||||||
"km": "ខ្មែរ",
|
"km": "ខ្មែរ",
|
||||||
@ -46,7 +46,7 @@
|
|||||||
"mn": "Монгол",
|
"mn": "Монгол",
|
||||||
"mr": "मराठी",
|
"mr": "मराठी",
|
||||||
"nl": "Nederlands",
|
"nl": "Nederlands",
|
||||||
"no": "Norsk - bokmål",
|
"no": "Norsk",
|
||||||
"pl": "Polski",
|
"pl": "Polski",
|
||||||
"pt": "Português - Portugal",
|
"pt": "Português - Portugal",
|
||||||
"pt-br": "Português - Brasil",
|
"pt-br": "Português - Brasil",
|
||||||
|
@ -37,7 +37,10 @@
|
|||||||
"ionic:serve:before": "gulp",
|
"ionic:serve:before": "gulp",
|
||||||
"ionic:serve": "cross-env-shell ./scripts/serve.sh",
|
"ionic:serve": "cross-env-shell ./scripts/serve.sh",
|
||||||
"ionic:build:before": "gulp",
|
"ionic:build:before": "gulp",
|
||||||
"postinstall": "patch-package"
|
"postinstall": "patch-package",
|
||||||
|
"lang:update-langpacks": "./scripts/update_langpacks.sh",
|
||||||
|
"lang:detect-langpacks": "./scripts/update_langpacks.sh detect",
|
||||||
|
"lang:create-langindex": "./scripts/create_langindex.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "~10.0.14",
|
"@angular/animations": "~10.0.14",
|
||||||
|
@ -3,323 +3,22 @@
|
|||||||
# Script to create langindex from available language packs.
|
# Script to create langindex from available language packs.
|
||||||
# ./create_langindex.sh [findbetter]
|
# ./create_langindex.sh [findbetter]
|
||||||
# If findbetter is set it will try to find a better solution for every key.
|
# If findbetter is set it will try to find a better solution for every key.
|
||||||
# Edit lang_functions.sh LANGPACKSFOLDER variable to match your system's
|
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
DIR="${BASH_SOURCE%/*}"
|
||||||
|
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
|
||||||
|
|
||||||
|
cd $DIR
|
||||||
|
|
||||||
source "functions.sh"
|
source "functions.sh"
|
||||||
source "lang_functions.sh"
|
source "lang_functions.sh"
|
||||||
|
source "create_langindex_functions.sh"
|
||||||
#Saves or updates a key on langindex_old.json
|
|
||||||
function save_key {
|
|
||||||
local key=$1
|
|
||||||
local found=$2
|
|
||||||
|
|
||||||
print_ok "$key=$found"
|
|
||||||
echo "{\"$key\": \"$found\"}" > langindex_old.json
|
|
||||||
jq -s '.[0] + .[1]' langindex.json langindex_old.json > langindex_new.json
|
|
||||||
mv langindex_new.json langindex.json
|
|
||||||
}
|
|
||||||
|
|
||||||
#Removes a key on langindex_old.json
|
|
||||||
function remove_key {
|
|
||||||
local key=$1
|
|
||||||
|
|
||||||
cat langindex.json | jq 'del(."'$key'")' > langindex_new.json
|
|
||||||
mv langindex_new.json langindex.json
|
|
||||||
print_ok "Deleted unused key $key"
|
|
||||||
}
|
|
||||||
|
|
||||||
#Check if and i exists in php file
|
|
||||||
function exists_in_file {
|
|
||||||
local file=$1
|
|
||||||
local id=$2
|
|
||||||
|
|
||||||
file=`echo $file | sed s/^mod_workshop_assessment/workshopform/1`
|
|
||||||
file=`echo $file | sed s/^mod_assign_/assign/1`
|
|
||||||
file=`echo $file | sed s/^mod_//1`
|
|
||||||
|
|
||||||
completeFile="$LANGPACKSFOLDER/en/$file.php"
|
|
||||||
if [ -f "$completeFile" ]; then
|
|
||||||
foundInFile=`grep "string\[\'$id\'\]" $completeFile`
|
|
||||||
if [ ! -z "$foundInFile" ]; then
|
|
||||||
coincidence=1
|
|
||||||
found=$file
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
coincidence=0
|
|
||||||
found=0
|
|
||||||
}
|
|
||||||
|
|
||||||
#Checks if a key exists on the original local_moodlemobileapp.php
|
|
||||||
function exists_in_mobile {
|
|
||||||
local file='local_moodlemobileapp'
|
|
||||||
exists_in_file $file $key
|
|
||||||
}
|
|
||||||
|
|
||||||
function do_match {
|
|
||||||
match=${1/\{\{/\{}
|
|
||||||
match=${match/\}\}/\}}
|
|
||||||
filematch=""
|
|
||||||
|
|
||||||
coincidence=`grep "$match" $LANGPACKSFOLDER/en/*.php | wc -l`
|
|
||||||
if [ $coincidence -eq 1 ]; then
|
|
||||||
filematch=`grep "$match" $LANGPACKSFOLDER/en/*.php | cut -d'/' -f5 | cut -d'.' -f1`
|
|
||||||
exists_in_file $filematch $plainid
|
|
||||||
elif [ $coincidence -gt 0 ] && [ "$#" -gt 1 ]; then
|
|
||||||
print_message "$2"
|
|
||||||
tput setaf 6
|
|
||||||
grep "$match" $LANGPACKSFOLDER/en/*.php
|
|
||||||
else
|
|
||||||
coincidence=0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#Find if the id or the value can be found on files to help providing a solution.
|
|
||||||
function find_matches {
|
|
||||||
do_match "string\[\'$plainid\'\] = \'$value\'" "Found EXACT match for $key in the following paths"
|
|
||||||
if [ $coincidence -gt 0 ]; then
|
|
||||||
case=1
|
|
||||||
save_key $key "TBD"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_match " = \'$value\'" "Found some string VALUES for $key in the following paths"
|
|
||||||
if [ $coincidence -gt 0 ]; then
|
|
||||||
case=2
|
|
||||||
save_key $key "TBD"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_match "string\[\'$plainid\'\]" "Found some string KEYS for $key in the following paths, value $value"
|
|
||||||
if [ $coincidence -gt 0 ]; then
|
|
||||||
case=3
|
|
||||||
save_key $key "TBD"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_message "No match found for $key add it to local_moodlemobileapp"
|
|
||||||
save_key $key "local_moodlemobileapp"
|
|
||||||
}
|
|
||||||
|
|
||||||
function find_single_matches {
|
|
||||||
do_match "string\[\'$plainid\'\] = \'$value\'"
|
|
||||||
if [ ! -z $filematch ] && [ $found != 0 ]; then
|
|
||||||
case=1
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_match " = \'$value\'"
|
|
||||||
if [ ! -z $filematch ] && [ $filematch != 'local_moodlemobileapp' ]; then
|
|
||||||
case=2
|
|
||||||
print_message "Found some string VALUES for $key in the following paths $filematch"
|
|
||||||
tput setaf 6
|
|
||||||
grep "$match" $LANGPACKSFOLDER/en/*.php
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
do_match "string\[\'$plainid\'\]"
|
|
||||||
if [ ! -z $filematch ] && [ $found != 0 ]; then
|
|
||||||
case=3
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#Tries to gues the file where the id will be found.
|
|
||||||
function guess_file {
|
|
||||||
local key=$1
|
|
||||||
local value=$2
|
|
||||||
|
|
||||||
local type=`echo $key | cut -d'.' -f1`
|
|
||||||
local component=`echo $key | cut -d'.' -f2`
|
|
||||||
local plainid=`echo $key | cut -d'.' -f3-`
|
|
||||||
|
|
||||||
if [ -z "$plainid" ]; then
|
|
||||||
plainid=$component
|
|
||||||
component='moodle'
|
|
||||||
fi
|
|
||||||
|
|
||||||
exists_in_file $component $plainid
|
|
||||||
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
tempid=`echo $plainid | sed s/^mod_//1`
|
|
||||||
if [ $component == 'moodle' ] && [ "$tempid" != "$plainid" ]; then
|
|
||||||
exists_in_file $plainid pluginname
|
|
||||||
|
|
||||||
if [ $found != 0 ]; then
|
|
||||||
found=$found/pluginname
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Not found in file, try in local_moodlemobileapp
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
exists_in_mobile
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Still not found, if only found in one file, use it.
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
find_single_matches
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Last fallback.
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
exists_in_file 'moodle' $plainid
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
find_matches
|
|
||||||
else
|
|
||||||
save_key $key $found
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function current_translation_exists {
|
|
||||||
local key=$1
|
|
||||||
local current=$2
|
|
||||||
local file=$3
|
|
||||||
|
|
||||||
plainid=`echo $key | cut -d'.' -f3-`
|
|
||||||
|
|
||||||
if [ -z "$plainid" ]; then
|
|
||||||
plainid=`echo $key | cut -d'.' -f2`
|
|
||||||
fi
|
|
||||||
|
|
||||||
local currentFile=`echo $current | cut -d'/' -f1`
|
|
||||||
local currentStr=`echo $current | cut -d'/' -f2-`
|
|
||||||
if [ $currentFile == $current ]; then
|
|
||||||
currentStr=$plainid
|
|
||||||
fi
|
|
||||||
|
|
||||||
exists_in_file $currentFile $currentStr
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
# Translation not found.
|
|
||||||
exec="jq -r .\"$key\" $file"
|
|
||||||
value=`$exec`
|
|
||||||
|
|
||||||
print_error "Translation of '$currentStr' not found in '$currentFile'"
|
|
||||||
|
|
||||||
guess_file $key "$value"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#Finds if there's a better file where to get the id from.
|
|
||||||
function find_better_file {
|
|
||||||
local key=$1
|
|
||||||
local value=$2
|
|
||||||
local current=$3
|
|
||||||
|
|
||||||
local type=`echo $key | cut -d'.' -f1`
|
|
||||||
local component=`echo $key | cut -d'.' -f2`
|
|
||||||
local plainid=`echo $key | cut -d'.' -f3-`
|
|
||||||
|
|
||||||
if [ -z "$plainid" ]; then
|
|
||||||
plainid=$component
|
|
||||||
component='moodle'
|
|
||||||
fi
|
|
||||||
|
|
||||||
local currentFile=`echo $current | cut -d'/' -f1`
|
|
||||||
local currentStr=`echo $current | cut -d'/' -f2-`
|
|
||||||
if [ $currentFile == $current ]; then
|
|
||||||
currentStr=$plainid
|
|
||||||
fi
|
|
||||||
|
|
||||||
exists_in_file $component $plainid
|
|
||||||
if [ $found != 0 ] && [ $currentStr == $plainid ]; then
|
|
||||||
if [ $found != $currentFile ]; then
|
|
||||||
print_ok "Key '$key' found in component, no need to replace old '$current'"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Still not found, if only found in one file, use it.
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
find_single_matches
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $found != 0 ] && [ $found != $currentFile ] && [ $case -lt 3 ]; then
|
|
||||||
print_message "Indexed string '$key' found in '$found' better than '$current'"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $currentFile == 'local_moodlemobileapp' ]; then
|
|
||||||
exists_in_mobile
|
|
||||||
else
|
|
||||||
exists_in_file $currentFile $currentStr
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $found == 0 ]; then
|
|
||||||
print_error "Indexed string '$key' not found on current place '$current'"
|
|
||||||
if [ $currentFile != 'local_moodlemobileapp' ]; then
|
|
||||||
print_error "Execute this on AMOS
|
|
||||||
CPY [$currentStr,$currentFile],[$key,local_moodlemobileapp]"
|
|
||||||
save_key $key "local_moodlemobileapp"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parses the file.
|
|
||||||
function parse_file {
|
|
||||||
findbetter=$2
|
|
||||||
keys=`jq -r 'keys[]' $1`
|
|
||||||
for key in $keys; do
|
|
||||||
# Check if already parsed.
|
|
||||||
exec="jq -r .\"$key\" langindex.json"
|
|
||||||
found=`$exec`
|
|
||||||
|
|
||||||
if [ -z "$found" ] || [ "$found" == 'null' ]; then
|
|
||||||
exec="jq -r .\"$key\" $1"
|
|
||||||
value=`$exec`
|
|
||||||
guess_file $key "$value"
|
|
||||||
else
|
|
||||||
if [ "$found" == 'donottranslate' ]; then
|
|
||||||
# Do nothing since is not translatable.
|
|
||||||
continue
|
|
||||||
elif [ ! -z "$findbetter" ]; then
|
|
||||||
exec="jq -r .\"$key\" $1"
|
|
||||||
value=`$exec`
|
|
||||||
find_better_file "$key" "$value" "$found"
|
|
||||||
elif [ "$found" != 'local_moodlemobileapp' ]; then
|
|
||||||
current_translation_exists "$key" "$found" "$1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Do some cleanup
|
|
||||||
langkeys=`jq -r 'keys[]' langindex.json`
|
|
||||||
findkeys="${keys[@]}"
|
|
||||||
for key in $langkeys; do
|
|
||||||
# Check if already used.
|
|
||||||
array_contains "$key" "$findkeys"
|
|
||||||
|
|
||||||
if [ -z "$found" ] || [ "$found" == 'null' ]; then
|
|
||||||
remove_key $key
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Checks if an array contains an string.
|
|
||||||
function array_contains {
|
|
||||||
local hayjack=$2
|
|
||||||
local needle=$1
|
|
||||||
found=''
|
|
||||||
for i in $hayjack; do
|
|
||||||
if [ "$i" == "$needle" ] ; then
|
|
||||||
found=$i
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
print_title 'Generating language from code...'
|
print_title 'Generating language from code...'
|
||||||
npx gulp lang
|
npx gulp lang
|
||||||
|
|
||||||
print_title 'Getting languages'
|
get_english
|
||||||
|
|
||||||
get_language en
|
|
||||||
|
|
||||||
print_title 'Processing file'
|
print_title 'Processing file'
|
||||||
#Create langindex.json if not exists.
|
#Create langindex.json if not exists.
|
||||||
@ -328,7 +27,7 @@ if [ ! -f 'langindex.json' ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
findbetter=$1
|
findbetter=$1
|
||||||
parse_file '../src/assets/lang/en.json' $findbetter
|
parse_file $findbetter
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
355
scripts/create_langindex_functions.sh
Normal file
355
scripts/create_langindex_functions.sh
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Functions used to create langidex.
|
||||||
|
#
|
||||||
|
|
||||||
|
SERVER_URL='https://download.moodle.org/'
|
||||||
|
|
||||||
|
# Downloads a file and if it's a zip file, unzip it.
|
||||||
|
function download_file {
|
||||||
|
local url=$1
|
||||||
|
local filename=$(basename ${url})
|
||||||
|
|
||||||
|
pushd $LANGPACKS_PATH > /dev/null
|
||||||
|
|
||||||
|
curl -s $url --output $filename > /dev/null
|
||||||
|
size=$(du -k "$filename" | cut -f 1)
|
||||||
|
if [ ! -n $filename ] || [ $size -le 1 ]; then
|
||||||
|
echo "Wrong or corrupt file $filename"
|
||||||
|
rm $filename
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $filename == *.zip ]]; then
|
||||||
|
local lang="${filename%.*}"
|
||||||
|
# Delete previous downloaded folder
|
||||||
|
rm -R $lang > /dev/null 2>&1> /dev/null
|
||||||
|
|
||||||
|
# Unzip
|
||||||
|
unzip -o -u $lang.zip > /dev/null
|
||||||
|
|
||||||
|
# Delete the zip
|
||||||
|
rm $filename
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_english {
|
||||||
|
if [ ! -d $LANGPACKS_PATH ]; then
|
||||||
|
mkdir $LANGPACKS_PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_app_version
|
||||||
|
|
||||||
|
echo "Getting English language..."
|
||||||
|
download_file "$SERVER_URL/download.php/direct/langpack/$LANGVERSION/en.zip"
|
||||||
|
}
|
||||||
|
|
||||||
|
#Saves or updates a key on langindex_old.json
|
||||||
|
function save_key {
|
||||||
|
local key=$1
|
||||||
|
local found=$2
|
||||||
|
|
||||||
|
print_ok "$key=$found"
|
||||||
|
echo "{\"$key\": \"$found\"}" > langindex_old.json
|
||||||
|
jq -s '.[0] + .[1]' langindex.json langindex_old.json > langindex_new.json
|
||||||
|
mv langindex_new.json langindex.json
|
||||||
|
}
|
||||||
|
|
||||||
|
#Removes a key on langindex_old.json
|
||||||
|
function remove_key {
|
||||||
|
local key=$1
|
||||||
|
|
||||||
|
cat langindex.json | jq 'del(."'$key'")' > langindex_new.json
|
||||||
|
mv langindex_new.json langindex.json
|
||||||
|
print_ok "Deleted unused key $key"
|
||||||
|
}
|
||||||
|
|
||||||
|
#Check if a lang id exists in php file
|
||||||
|
function exists_in_file {
|
||||||
|
local file=$1
|
||||||
|
local id=$2
|
||||||
|
|
||||||
|
file=`echo $file | sed s/^mod_workshop_assessment/workshopform/1`
|
||||||
|
file=`echo $file | sed s/^mod_assign_/assign/1`
|
||||||
|
file=`echo $file | sed s/^mod_//1`
|
||||||
|
|
||||||
|
completeFile="$LANGPACKS_PATH/en/$file.php"
|
||||||
|
if [ -f "$completeFile" ]; then
|
||||||
|
foundInFile=`grep "string\[\'$id\'\]" $completeFile`
|
||||||
|
if [ ! -z "$foundInFile" ]; then
|
||||||
|
coincidence=1
|
||||||
|
found=$file
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
coincidence=0
|
||||||
|
found=0
|
||||||
|
}
|
||||||
|
|
||||||
|
#Checks if a key exists on the original local_moodlemobileapp.php
|
||||||
|
function exists_in_mobile {
|
||||||
|
local file='local_moodlemobileapp'
|
||||||
|
exists_in_file $file $key
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_match {
|
||||||
|
match=${1/\{\{/\{}
|
||||||
|
match=${match/\}\}/\}}
|
||||||
|
filematch=""
|
||||||
|
|
||||||
|
coincidence=`grep "$match" $LANGPACKS_PATH/en/*.php | wc -l`
|
||||||
|
if [ $coincidence -eq 1 ]; then
|
||||||
|
filematch=`grep "$match" $LANGPACKS_PATH/en/*.php | cut -d'/' -f5 | cut -d'.' -f1`
|
||||||
|
exists_in_file $filematch $plainid
|
||||||
|
elif [ $coincidence -gt 0 ] && [ "$#" -gt 1 ]; then
|
||||||
|
print_message "$2"
|
||||||
|
tput setaf 6
|
||||||
|
grep "$match" $LANGPACKS_PATH/en/*.php
|
||||||
|
else
|
||||||
|
coincidence=0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#Find if the id or the value can be found on files to help providing a solution.
|
||||||
|
function find_matches {
|
||||||
|
do_match "string\[\'$plainid\'\] = \'$value\'" "Found EXACT match for $key in the following paths"
|
||||||
|
if [ $coincidence -gt 0 ]; then
|
||||||
|
case=1
|
||||||
|
save_key $key "TBD"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
do_match " = \'$value\'" "Found some string VALUES for $key in the following paths"
|
||||||
|
if [ $coincidence -gt 0 ]; then
|
||||||
|
case=2
|
||||||
|
save_key $key "TBD"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
do_match "string\[\'$plainid\'\]" "Found some string KEYS for $key in the following paths, value $value"
|
||||||
|
if [ $coincidence -gt 0 ]; then
|
||||||
|
case=3
|
||||||
|
save_key $key "TBD"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_message "No match found for $key add it to local_moodlemobileapp"
|
||||||
|
save_key $key "local_moodlemobileapp"
|
||||||
|
}
|
||||||
|
|
||||||
|
function find_single_matches {
|
||||||
|
do_match "string\[\'$plainid\'\] = \'$value\'"
|
||||||
|
if [ ! -z $filematch ] && [ $found != 0 ]; then
|
||||||
|
case=1
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
do_match " = \'$value\'"
|
||||||
|
if [ ! -z $filematch ] && [ $filematch != 'local_moodlemobileapp' ]; then
|
||||||
|
case=2
|
||||||
|
print_message "Found some string VALUES for $key in the following paths $filematch"
|
||||||
|
tput setaf 6
|
||||||
|
grep "$match" $LANGPACKS_PATH/en/*.php
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
do_match "string\[\'$plainid\'\]"
|
||||||
|
if [ ! -z $filematch ] && [ $found != 0 ]; then
|
||||||
|
case=3
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#Tries to gues the file where the id will be found.
|
||||||
|
function guess_file {
|
||||||
|
local key=$1
|
||||||
|
local value=$2
|
||||||
|
|
||||||
|
local type=`echo $key | cut -d'.' -f1`
|
||||||
|
local component=`echo $key | cut -d'.' -f2`
|
||||||
|
local plainid=`echo $key | cut -d'.' -f3-`
|
||||||
|
|
||||||
|
if [ -z "$plainid" ]; then
|
||||||
|
plainid=$component
|
||||||
|
component='moodle'
|
||||||
|
fi
|
||||||
|
|
||||||
|
exists_in_file $component $plainid
|
||||||
|
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
tempid=`echo $plainid | sed s/^mod_//1`
|
||||||
|
if [ $component == 'moodle' ] && [ "$tempid" != "$plainid" ]; then
|
||||||
|
exists_in_file $plainid pluginname
|
||||||
|
|
||||||
|
if [ $found != 0 ]; then
|
||||||
|
found=$found/pluginname
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Not found in file, try in local_moodlemobileapp
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
exists_in_mobile
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Still not found, if only found in one file, use it.
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
find_single_matches
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Last fallback.
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
exists_in_file 'moodle' $plainid
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
find_matches
|
||||||
|
else
|
||||||
|
save_key $key $found
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function current_translation_exists {
|
||||||
|
local key=$1
|
||||||
|
local current=$2
|
||||||
|
local file=$3
|
||||||
|
|
||||||
|
plainid=`echo $key | cut -d'.' -f3-`
|
||||||
|
|
||||||
|
if [ -z "$plainid" ]; then
|
||||||
|
plainid=`echo $key | cut -d'.' -f2`
|
||||||
|
fi
|
||||||
|
|
||||||
|
local currentFile=`echo $current | cut -d'/' -f1`
|
||||||
|
local currentStr=`echo $current | cut -d'/' -f2-`
|
||||||
|
if [ $currentFile == $current ]; then
|
||||||
|
currentStr=$plainid
|
||||||
|
fi
|
||||||
|
|
||||||
|
exists_in_file $currentFile $currentStr
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
# Translation not found.
|
||||||
|
exec="jq -r .\"$key\" $file"
|
||||||
|
value=`$exec`
|
||||||
|
|
||||||
|
print_error "Translation of '$currentStr' not found in '$currentFile'"
|
||||||
|
|
||||||
|
guess_file $key "$value"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#Finds if there's a better file where to get the id from.
|
||||||
|
function find_better_file {
|
||||||
|
local key=$1
|
||||||
|
local value=$2
|
||||||
|
local current=$3
|
||||||
|
|
||||||
|
local type=`echo $key | cut -d'.' -f1`
|
||||||
|
local component=`echo $key | cut -d'.' -f2`
|
||||||
|
local plainid=`echo $key | cut -d'.' -f3-`
|
||||||
|
|
||||||
|
if [ -z "$plainid" ]; then
|
||||||
|
plainid=$component
|
||||||
|
component='moodle'
|
||||||
|
fi
|
||||||
|
|
||||||
|
local currentFile=`echo $current | cut -d'/' -f1`
|
||||||
|
local currentStr=`echo $current | cut -d'/' -f2-`
|
||||||
|
if [ $currentFile == $current ]; then
|
||||||
|
currentStr=$plainid
|
||||||
|
fi
|
||||||
|
|
||||||
|
exists_in_file $component $plainid
|
||||||
|
if [ $found != 0 ] && [ $currentStr == $plainid ]; then
|
||||||
|
if [ $found != $currentFile ]; then
|
||||||
|
print_ok "Key '$key' found in component, no need to replace old '$current'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Still not found, if only found in one file, use it.
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
find_single_matches
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $found != 0 ] && [ $found != $currentFile ] && [ $case -lt 3 ]; then
|
||||||
|
print_message "Indexed string '$key' found in '$found' better than '$current'"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $currentFile == 'local_moodlemobileapp' ]; then
|
||||||
|
exists_in_mobile
|
||||||
|
else
|
||||||
|
exists_in_file $currentFile $currentStr
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $found == 0 ]; then
|
||||||
|
print_error "Indexed string '$key' not found on current place '$current'"
|
||||||
|
if [ $currentFile != 'local_moodlemobileapp' ]; then
|
||||||
|
print_error "Execute this on AMOS
|
||||||
|
CPY [$currentStr,$currentFile],[$key,local_moodlemobileapp]"
|
||||||
|
save_key $key "local_moodlemobileapp"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parses the file.
|
||||||
|
function parse_file {
|
||||||
|
file="$LANG_PATH/en.json"
|
||||||
|
findbetter=$1
|
||||||
|
|
||||||
|
keys=`jq -r 'keys[]' $file`
|
||||||
|
for key in $keys; do
|
||||||
|
# Check if already parsed.
|
||||||
|
exec="jq -r .\"$key\" langindex.json"
|
||||||
|
found=`$exec`
|
||||||
|
|
||||||
|
if [ -z "$found" ] || [ "$found" == 'null' ]; then
|
||||||
|
exec="jq -r .\"$key\" $1"
|
||||||
|
value=`$exec`
|
||||||
|
guess_file $key "$value"
|
||||||
|
else
|
||||||
|
if [ "$found" == 'donottranslate' ]; then
|
||||||
|
# Do nothing since is not translatable.
|
||||||
|
continue
|
||||||
|
elif [ ! -z "$findbetter" ]; then
|
||||||
|
exec="jq -r .\"$key\" $1"
|
||||||
|
value=`$exec`
|
||||||
|
find_better_file "$key" "$value" "$found"
|
||||||
|
elif [ "$found" != 'local_moodlemobileapp' ]; then
|
||||||
|
current_translation_exists "$key" "$found" "$1"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Do some cleanup
|
||||||
|
langkeys=`jq -r 'keys[]' langindex.json`
|
||||||
|
findkeys="${keys[@]}"
|
||||||
|
for key in $langkeys; do
|
||||||
|
# Check if already used.
|
||||||
|
array_contains "$key" "$findkeys"
|
||||||
|
|
||||||
|
if [ -z "$found" ] || [ "$found" == 'null' ]; then
|
||||||
|
remove_key $key
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Checks if an array contains an string.
|
||||||
|
function array_contains {
|
||||||
|
local hayjack=$2
|
||||||
|
local needle=$1
|
||||||
|
found=''
|
||||||
|
for i in $hayjack; do
|
||||||
|
if [ "$i" == "$needle" ] ; then
|
||||||
|
found=$i
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
@ -1,541 +0,0 @@
|
|||||||
<?php
|
|
||||||
// This file is part of Moodle - http://moodle.org/
|
|
||||||
//
|
|
||||||
// Moodle is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Moodle is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper functions converting moodle strings to json.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function detect_languages($languages) {
|
|
||||||
echo "\n\n\n";
|
|
||||||
|
|
||||||
$all_languages = glob(LANGPACKSFOLDER.'/*' , GLOB_ONLYDIR);
|
|
||||||
function get_lang_from_dir($dir) {
|
|
||||||
return str_replace('_', '-', explode('/', $dir)[3]);
|
|
||||||
}
|
|
||||||
function get_lang_not_wp($langname) {
|
|
||||||
return (substr($langname, -3) !== '-wp');
|
|
||||||
}
|
|
||||||
$all_languages = array_map('get_lang_from_dir', $all_languages);
|
|
||||||
$all_languages = array_filter($all_languages, 'get_lang_not_wp');
|
|
||||||
|
|
||||||
$detect_lang = array_diff($all_languages, $languages);
|
|
||||||
$new_langs = [];
|
|
||||||
foreach ($detect_lang as $lang) {
|
|
||||||
$new = detect_lang($lang);
|
|
||||||
if ($new) {
|
|
||||||
$new_langs[$lang] = $lang;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $new_langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
function build_languages($languages, $added_langs = []) {
|
|
||||||
// Process the languages.
|
|
||||||
foreach ($languages as $lang) {
|
|
||||||
if (build_lang($lang)) {
|
|
||||||
$added_langs[$lang] = $lang;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $added_langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads lang index keys.
|
|
||||||
*/
|
|
||||||
function load_langindex() {
|
|
||||||
global $STATS;
|
|
||||||
global $LANGINDEX;
|
|
||||||
|
|
||||||
$local = 0;
|
|
||||||
$total = 0;
|
|
||||||
// Process the index file, just once.
|
|
||||||
$langindexjson = load_json('langindex.json');
|
|
||||||
|
|
||||||
$LANGINDEX = [];
|
|
||||||
foreach ($langindexjson as $appkey => $value) {
|
|
||||||
if ($value == APPMODULENAME) {
|
|
||||||
$file = $value;
|
|
||||||
$lmskey = $appkey;
|
|
||||||
$local++;
|
|
||||||
} else {
|
|
||||||
$exp = explode('/', $value, 2);
|
|
||||||
$file = $exp[0];
|
|
||||||
if (count($exp) == 2) {
|
|
||||||
$lmskey = $exp[1];
|
|
||||||
} else {
|
|
||||||
$exp = explode('.', $appkey, 3);
|
|
||||||
|
|
||||||
if (count($exp) == 3) {
|
|
||||||
$lmskey = $exp[2];
|
|
||||||
} else {
|
|
||||||
$lmskey = $exp[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($LANGINDEX[$file])) {
|
|
||||||
$LANGINDEX[$file] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$LANGINDEX[$file][$appkey] = $lmskey;
|
|
||||||
$total++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$STATS = new StdClass();
|
|
||||||
$STATS->local = $local;
|
|
||||||
$STATS->total = $total;
|
|
||||||
|
|
||||||
echo "Total strings to translate $total ($local local)\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add lang names to config file.
|
|
||||||
*
|
|
||||||
* @param $langs Array of language codes to add.
|
|
||||||
* @param $config Loaded config file.
|
|
||||||
*/
|
|
||||||
function add_langs_to_config($langs, $config) {
|
|
||||||
$changed = false;
|
|
||||||
$config_langs = get_object_vars($config['languages']);
|
|
||||||
foreach ($langs as $lang) {
|
|
||||||
if (!isset($config_langs[$lang])) {
|
|
||||||
$langfoldername = get_langfolder($lang);
|
|
||||||
|
|
||||||
$lmsstring = get_translation_strings($langfoldername, 'langconfig');
|
|
||||||
$config['languages']->$lang = $lmsstring['thislanguage'];
|
|
||||||
$changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($changed) {
|
|
||||||
// Sort languages by key.
|
|
||||||
$config['languages'] = json_decode( json_encode( $config['languages'] ), true );
|
|
||||||
ksort($config['languages']);
|
|
||||||
$config['languages'] = json_decode( json_encode( $config['languages'] ), false );
|
|
||||||
save_json(CONFIG, $config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save json data.
|
|
||||||
*
|
|
||||||
* @param $path Path of the file to load.
|
|
||||||
* @param $content Content string to save.
|
|
||||||
*/
|
|
||||||
function save_json($path, $content) {
|
|
||||||
file_put_contents($path, str_replace('\/', '/', json_encode($content, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))."\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load json data.
|
|
||||||
*
|
|
||||||
* @param $path Path of the file to load.
|
|
||||||
* @return Associative array obtained from json.
|
|
||||||
*/
|
|
||||||
function load_json($path) {
|
|
||||||
$file = file_get_contents($path);
|
|
||||||
return (array) json_decode($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get's lang folder from lang code.
|
|
||||||
*
|
|
||||||
* @param $lang Lang code.
|
|
||||||
* @return Folder path.
|
|
||||||
*/
|
|
||||||
function get_langfolder($lang) {
|
|
||||||
$folder = LANGPACKSFOLDER.'/'.str_replace('-', '_', $lang);
|
|
||||||
if (!is_dir($folder) || !is_file($folder.'/langconfig.php')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $folder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import translation file from langpack and returns it.
|
|
||||||
*
|
|
||||||
* @param $langfoldername Lang folder path.
|
|
||||||
* @param $file File name (excluding extension).
|
|
||||||
* @param $override_folder If needed, the folder of the file to override strings.
|
|
||||||
* @return String array.
|
|
||||||
*/
|
|
||||||
function get_translation_strings($langfoldername, $file, $override_folder = false) {
|
|
||||||
$lmsstring = import_translation_strings($langfoldername, $file);
|
|
||||||
if ($override_folder) {
|
|
||||||
$override = import_translation_strings($override_folder, $file);
|
|
||||||
$lmsstring = array_merge($lmsstring, $override);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $lmsstring;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import translation file from langpack and returns it.
|
|
||||||
*
|
|
||||||
* @param $langfoldername Lang folder path.
|
|
||||||
* @param $file File name (excluding extension).
|
|
||||||
* @return String array.
|
|
||||||
*/
|
|
||||||
function import_translation_strings($langfoldername, $file) {
|
|
||||||
|
|
||||||
$path = $langfoldername.'/'.$file.'.php';
|
|
||||||
// Apply translations.
|
|
||||||
if (!file_exists($path)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$string = [];
|
|
||||||
|
|
||||||
include($path);
|
|
||||||
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build translations files from langpack.
|
|
||||||
*
|
|
||||||
* @param lang Language code.
|
|
||||||
* @return Wether it succeeded.
|
|
||||||
*/
|
|
||||||
function build_lang($lang) {
|
|
||||||
global $STATS;
|
|
||||||
global $LANGINDEX;
|
|
||||||
|
|
||||||
$langfoldername = get_langfolder($lang);
|
|
||||||
if (!$langfoldername) {
|
|
||||||
echo "Cannot translate $lang, folder not found";
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OVERRIDE_LANG_SUFIX) {
|
|
||||||
$override_langfolder = get_langfolder($lang.OVERRIDE_LANG_SUFIX);
|
|
||||||
} else {
|
|
||||||
$override_langfolder = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$total = $STATS->total;
|
|
||||||
$local = 0;
|
|
||||||
|
|
||||||
$langparts = explode('-', $lang, 2);
|
|
||||||
$parentname = $langparts[0] ? $langparts[0] : "";
|
|
||||||
$parent = "";
|
|
||||||
|
|
||||||
echo "Processing $lang";
|
|
||||||
// Check parent language exists.
|
|
||||||
if ($parentname != $lang && get_langfolder($parentname)) {
|
|
||||||
echo " ($parentname)";
|
|
||||||
$parent = $parentname;
|
|
||||||
}
|
|
||||||
|
|
||||||
$langFile = false;
|
|
||||||
if (file_exists(ASSETSPATH.$lang.'.json')) {
|
|
||||||
// Load lang files just once.
|
|
||||||
$langFile = load_json(ASSETSPATH.$lang.'.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
$translations = [];
|
|
||||||
// Add the translation to the array.
|
|
||||||
foreach ($LANGINDEX as $file => $keys) {
|
|
||||||
$lmsstring = get_translation_strings($langfoldername, $file, $override_langfolder);
|
|
||||||
foreach ($keys as $appkey => $lmskey) {
|
|
||||||
// Apply translations.
|
|
||||||
if (empty($lmsstring)) {
|
|
||||||
if ($file == 'donottranslate') {
|
|
||||||
// Restore it form the json.
|
|
||||||
if ($langFile && is_array($langFile) && isset($langFile[$appkey])) {
|
|
||||||
$translations[$appkey] = $langFile[$appkey];
|
|
||||||
} else {
|
|
||||||
// If not present, do not count it in the total.
|
|
||||||
$total--;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOTRANSLATE) {
|
|
||||||
echo "\n\t\tTo translate $lmskey on $file";
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($lmsstring[$lmskey]) || ($lang == 'en' && $file == APPMODULENAME)) {
|
|
||||||
// Not yet translated. Do not override.
|
|
||||||
if ($langFile && is_array($langFile) && isset($langFile[$appkey])) {
|
|
||||||
$translations[$appkey] = $langFile[$appkey];
|
|
||||||
|
|
||||||
if ($file == APPMODULENAME) {
|
|
||||||
$local++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (TOTRANSLATE && !isset($lmsstring[$lmskey])) {
|
|
||||||
echo "\n\t\tTo translate $lmskey on $file";
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$text = $lmsstring[$lmskey];
|
|
||||||
|
|
||||||
if ($file != APPMODULENAME) {
|
|
||||||
$text = str_replace('$a->@', '$a.', $text);
|
|
||||||
$text = str_replace('$a->', '$a.', $text);
|
|
||||||
$text = str_replace('{$a', '{{$a', $text);
|
|
||||||
$text = str_replace('}', '}}', $text);
|
|
||||||
$text = preg_replace('/@@.+?@@(<br>)?\\s*/', '', $text);
|
|
||||||
// Prevent double.
|
|
||||||
$text = str_replace(['{{{', '}}}'], ['{{', '}}'], $text);
|
|
||||||
} else {
|
|
||||||
// @TODO: Remove that line when core.cannotconnect and core.login.invalidmoodleversion are completelly changed to use $a
|
|
||||||
if (($appkey == 'core.cannotconnect' || $appkey == 'core.login.invalidmoodleversion') && strpos($text, '2.4')) {
|
|
||||||
$text = str_replace('2.4', '{{$a}}', $text);
|
|
||||||
}
|
|
||||||
$local++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$translations[$appkey] = html_entity_decode($text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($parent)) {
|
|
||||||
$translations['core.parentlanguage'] = $parent;
|
|
||||||
} else if (isset($translations['core.parentlanguage'])) {
|
|
||||||
unset($translations['core.parentlanguage']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort and save.
|
|
||||||
ksort($translations);
|
|
||||||
save_json(ASSETSPATH.$lang.'.json', $translations);
|
|
||||||
|
|
||||||
$success = count($translations);
|
|
||||||
$percentage = floor($success/$total * 100);
|
|
||||||
$bar = progressbar($percentage);
|
|
||||||
if (strlen($lang) <= 2 && !$parent) {
|
|
||||||
echo "\t";
|
|
||||||
}
|
|
||||||
echo "\t\t$success of $total -> $percentage% $bar ($local local)\n";
|
|
||||||
|
|
||||||
if ($lang == 'en') {
|
|
||||||
generate_local_module_file($LANGINDEX[APPMODULENAME], $translations);
|
|
||||||
override_component_lang_files($translations);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an ASCII progress bar.
|
|
||||||
*
|
|
||||||
* @param $percentage Done part.
|
|
||||||
* @param $length Length of the text.
|
|
||||||
* @return Text generated.
|
|
||||||
*/
|
|
||||||
function progressbar($percentage, $length = 10) {
|
|
||||||
$done = floor($percentage / $length);
|
|
||||||
return "\t".str_repeat('=', $done) . str_repeat('-', $length - $done);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check translations on langpack and detects if the language should be added.
|
|
||||||
*
|
|
||||||
* @param lang Language code.
|
|
||||||
* @return If the file should be added to the app.
|
|
||||||
*/
|
|
||||||
function detect_lang($lang) {
|
|
||||||
global $STATS;
|
|
||||||
global $LANGINDEX;
|
|
||||||
|
|
||||||
$langfoldername = get_langfolder($lang);
|
|
||||||
if (!$langfoldername) {
|
|
||||||
echo "Cannot translate $lang, folder not found";
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$total = $STATS->total;
|
|
||||||
$success = 0;
|
|
||||||
$local = 0;
|
|
||||||
|
|
||||||
$lmsstring = get_translation_strings($langfoldername, 'langconfig');
|
|
||||||
$parent = isset($lmsstring['parentlanguage']) ? $lmsstring['parentlanguage'] : "";
|
|
||||||
if (!isset($lmsstring['thislanguage'])) {
|
|
||||||
echo "Cannot translate $lang, translated name not found";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = $lang;
|
|
||||||
if ($parent != "" && $parent != $lang) {
|
|
||||||
$title .= " ($parent)";
|
|
||||||
}
|
|
||||||
$langname = $lmsstring['thislanguage'];
|
|
||||||
$title .= " ".$langname." -D";
|
|
||||||
|
|
||||||
$lmsstring = get_translation_strings($langfoldername, APPMODULENAME);
|
|
||||||
if (!empty($lmsstring)) {
|
|
||||||
// Add the translation to the array.
|
|
||||||
foreach ($LANGINDEX as $file => $keys) {
|
|
||||||
$lmsstring = get_translation_strings($langfoldername, $file);
|
|
||||||
|
|
||||||
// Apply translations.
|
|
||||||
if (empty($lmsstring)) {
|
|
||||||
// Do not count non translatable in the totals.
|
|
||||||
if ($file == 'donottranslate') {
|
|
||||||
$total -= count($keys);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($keys as $lmskey) {
|
|
||||||
if (!isset($lmsstring[$lmskey])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($file == APPMODULENAME) {
|
|
||||||
$local++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$success++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Checking ".$title.str_repeat("\t", 7 - floor(mb_strlen($title, 'UTF-8')/8));
|
|
||||||
|
|
||||||
if ($local == 0) {
|
|
||||||
echo "\tNo Mobile App strings found\n";
|
|
||||||
} else {
|
|
||||||
$percentage = floor($success/$total * 100);
|
|
||||||
$bar = progressbar($percentage);
|
|
||||||
|
|
||||||
echo "\t$success of $total -> $percentage% $bar ($local local)";
|
|
||||||
if (($percentage > 75 && $local > 50) || ($percentage > 50 && $local > 75)) {
|
|
||||||
echo " \t DETECTED\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
echo "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save a key - value pair into a json file.
|
|
||||||
*
|
|
||||||
* @param key Key of the json object.
|
|
||||||
* @param value Value of the json object.
|
|
||||||
* @param filePath Path of the json file.
|
|
||||||
*/
|
|
||||||
function save_key($key, $value, $filePath) {
|
|
||||||
$file = load_json($filePath);
|
|
||||||
$value = html_entity_decode($value);
|
|
||||||
if (!isset($file[$key]) || $file[$key] != $value) {
|
|
||||||
$file[$key] = $value;
|
|
||||||
ksort($file);
|
|
||||||
save_json($filePath, $file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take newer ENGLISH translations from the langpacks and applies it to the app lang.json files.
|
|
||||||
*
|
|
||||||
* @param [array] $translations English translations.
|
|
||||||
*/
|
|
||||||
function override_component_lang_files($translations) {
|
|
||||||
echo "Override component lang files.\n";
|
|
||||||
foreach ($translations as $key => $value) {
|
|
||||||
$path = '../src/';
|
|
||||||
$exp = explode('.', $key, 3);
|
|
||||||
|
|
||||||
$type = $exp[0];
|
|
||||||
if (count($exp) == 3) {
|
|
||||||
$component = $exp[1];
|
|
||||||
$plainid = $exp[2];
|
|
||||||
} else {
|
|
||||||
$component = 'moodle';
|
|
||||||
$plainid = $exp[1];
|
|
||||||
}
|
|
||||||
switch($type) {
|
|
||||||
case 'core':
|
|
||||||
if ($component == 'moodle') {
|
|
||||||
$path .= 'core/lang.json';
|
|
||||||
} else {
|
|
||||||
$path .= 'core/features/'.str_replace('_', '/', $component).'/lang.json';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'addon':
|
|
||||||
$path .= 'addons/'.str_replace('_', '/', $component).'/lang.json';
|
|
||||||
break;
|
|
||||||
case 'assets':
|
|
||||||
$path .= $type.'/'.$component.'.json';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$path .= $type.'/lang.json';
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_file($path)) {
|
|
||||||
save_key($plainid, $value, $path);
|
|
||||||
} else {
|
|
||||||
echo "Cannot override: $path not found.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates local module file to update languages in AMOS.
|
|
||||||
*
|
|
||||||
* @param [array] $appindex Translation appindex.
|
|
||||||
* @param [array] $translations English translations.
|
|
||||||
*/
|
|
||||||
function generate_local_module_file($appindex, $translations) {
|
|
||||||
echo 'Generate '.APPMODULENAME."\n";
|
|
||||||
|
|
||||||
$lmsstring = "";
|
|
||||||
foreach ($appindex as $appkey => $lmskey) {
|
|
||||||
if (isset($translations[$appkey])) {
|
|
||||||
$lmsstring .= '$string[\''.$appkey.'\'] = \''.str_replace("'", "\'", $translations[$appkey]).'\';'."\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($lmsstring)) {
|
|
||||||
echo "ERROR, translations not found, you probably didn't run gulp lang!\n";
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$filepath = '../../moodle-'.APPMODULENAME.'/lang/en/'.APPMODULENAME.'.php';
|
|
||||||
$filecontents = file_get_contents($filepath);
|
|
||||||
|
|
||||||
$startcomment = "/* AUTO START */\n";
|
|
||||||
$endcomment = '/* AUTO END */';
|
|
||||||
|
|
||||||
$start = strpos($filecontents, $startcomment);
|
|
||||||
$start = $start === false ? 0 : $start + strlen($startcomment);
|
|
||||||
|
|
||||||
$end = strpos($filecontents, $endcomment, $start);
|
|
||||||
$end = $end === false ? strlen($filecontents) : $end;
|
|
||||||
|
|
||||||
$filecontents = substr_replace($filecontents, $lmsstring, $start, $end - $start);
|
|
||||||
|
|
||||||
if (substr($filecontents, -2) != "\n\n") {
|
|
||||||
$filecontents .= "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
file_put_contents($filepath, $filecontents);
|
|
||||||
}
|
|
156
scripts/lang_functions.sh
Executable file → Normal file
156
scripts/lang_functions.sh
Executable file → Normal file
@ -1,49 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Functions to fetch languages.
|
# Common functions to fetch languages.
|
||||||
#
|
#
|
||||||
|
|
||||||
LANGPACKSFOLDER='../../moodle-langpacks' # Langpacks will be downloaded here.
|
LANG_PATH='../src/assets/lang'
|
||||||
BUCKET='moodle-lang-prod'
|
SUFFIX='' # Determines suffix of the langpacks to be merged. Ie, using wp will include en.json and en_wp.json
|
||||||
MOODLEORG_URL='https://download.moodle.org/download.php/direct/langpack'
|
# (and the later will override the earlier).
|
||||||
DEFAULT_LASTVERSION='4.2' # Update it every version.
|
LANGPACKS_PATH='/tmp/moodleapp-lang'
|
||||||
|
|
||||||
# Checks if AWS is available and configured.
|
# Get the version of the Moodle App to fetch latest languages.
|
||||||
function check_aws {
|
function get_app_version {
|
||||||
if [ ! -z $AWS_SERVICE ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
export AWS_SERVICE=1
|
|
||||||
|
|
||||||
aws --version &> /dev/null
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
export AWS_SERVICE=0
|
|
||||||
echo 'AWS not installed. Check https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for more info.'
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# In order to login to AWS, use credentials file or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY vars.
|
|
||||||
if [ ! -f ~/.aws/credentials ] && ([ -z "$AWS_ACCESS_KEY_ID" ] || [ -z "$AWS_SECRET_ACCESS_KEY" ]); then
|
|
||||||
export AWS_SERVICE=0
|
|
||||||
echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.'
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function list_aws_files {
|
|
||||||
local folder="$1"
|
|
||||||
check_aws
|
|
||||||
|
|
||||||
if [ $AWS_SERVICE -eq 1 ]; then
|
|
||||||
export AWS_FOLDERS=`aws s3 ls s3://$BUCKET/$1`
|
|
||||||
else
|
|
||||||
export AWS_FOLDERS=[]
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get last version of Moodle to fetch latest languages.
|
|
||||||
function get_lang_version {
|
|
||||||
if [ ! -z "${LANGVERSION}" ]; then
|
if [ ! -z "${LANGVERSION}" ]; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@ -55,110 +21,6 @@ function get_lang_version {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
list_aws_files ''
|
echo "Cannot decide version"
|
||||||
LANGVERSION=''
|
exit 1
|
||||||
for folder in $AWS_FOLDERS; do
|
|
||||||
if [ $folder != 'PRE' ]; then
|
|
||||||
LANGVERSION=${folder/\//}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ! -z "${LANGVERSION}" ]; then
|
|
||||||
echo "Using last version $LANGVERSION detected"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
LANGVERSION=$DEFAULT_LASTVERSION
|
|
||||||
echo "Using default version $LANGVERSION"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create langfolder
|
|
||||||
function create_langfolder {
|
|
||||||
if [ ! -d $LANGPACKSFOLDER ]; then
|
|
||||||
mkdir $LANGPACKSFOLDER
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get language list from the installed ones (will not discover new translations).
|
|
||||||
function get_language_folders {
|
|
||||||
list_aws_files "$LANGVERSION/"
|
|
||||||
|
|
||||||
langs=""
|
|
||||||
for file in $AWS_FOLDERS; do
|
|
||||||
if [[ "$file" == *.zip ]]; then
|
|
||||||
file=${file/\.zip/}
|
|
||||||
langs+="$file "
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "${langs}" ]; then
|
|
||||||
# Get language list from the installed ones (will not discover new translations).
|
|
||||||
echo "Fallback language list will only get current installation languages"
|
|
||||||
langs=`jq -r '.languages | keys[]' ../moodle.config.json`
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Entry function to get a language file.
|
|
||||||
function get_language {
|
|
||||||
lang=$1
|
|
||||||
lang=${lang/-/_}
|
|
||||||
|
|
||||||
get_lang_version
|
|
||||||
|
|
||||||
create_langfolder
|
|
||||||
|
|
||||||
echo "Getting $lang language"
|
|
||||||
|
|
||||||
pushd $LANGPACKSFOLDER > /dev/null
|
|
||||||
|
|
||||||
curl -s $MOODLEORG_URL/$LANGVERSION/$lang.zip --output $lang.zip > /dev/null
|
|
||||||
size=$(du -k "$lang.zip" | cut -f 1)
|
|
||||||
if [ ! -n $lang.zip ] || [ $size -le 1 ]; then
|
|
||||||
echo "Wrong language name or corrupt file for $lang"
|
|
||||||
rm $lang.zip
|
|
||||||
|
|
||||||
popd > /dev/null
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -R $lang > /dev/null 2>&1> /dev/null
|
|
||||||
unzip -o -u $lang.zip > /dev/null
|
|
||||||
|
|
||||||
# This is the AWS version to get the language but right now it's slower.
|
|
||||||
# aws s3 cp s3://$BUCKET/$LANGVERSION/$lang.zip . > /dev/null
|
|
||||||
|
|
||||||
rm $lang.zip
|
|
||||||
popd > /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Entry function to get all language files.
|
|
||||||
function get_languages {
|
|
||||||
suffix=$1
|
|
||||||
if [ -z $suffix ]; then
|
|
||||||
suffix=''
|
|
||||||
fi
|
|
||||||
|
|
||||||
get_lang_version
|
|
||||||
|
|
||||||
if [ -d $LANGPACKSFOLDER ]; then
|
|
||||||
lastupdate=`date -r $LANGPACKSFOLDER +%s`
|
|
||||||
currenttime=`date +%s`
|
|
||||||
ellapsedtime=$((currenttime - lastupdate))
|
|
||||||
if [ $ellapsedtime -lt 3600 ]; then
|
|
||||||
echo 'Recently updated, skip update languages'
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
create_langfolder
|
|
||||||
fi
|
|
||||||
|
|
||||||
get_language_folders
|
|
||||||
|
|
||||||
for lang in $langs; do
|
|
||||||
get_language "$lang"
|
|
||||||
|
|
||||||
if [ ! -z $suffix ]; then
|
|
||||||
get_language "$lang$suffix"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
// This file is part of Moodle - http://moodle.org/
|
|
||||||
//
|
|
||||||
// Moodle is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Moodle is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Script for converting moodle strings to json.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Check we are in CLI.
|
|
||||||
if (isset($_SERVER['REMOTE_ADDR'])) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
define('MOODLE_INTERNAL', 1);
|
|
||||||
define('LANGPACKSFOLDER', '../../moodle-langpacks');
|
|
||||||
define('APPMODULENAME','local_moodlemobileapp');
|
|
||||||
define('ASSETSPATH', '../src/assets/lang/');
|
|
||||||
define('CONFIG', '../moodle.config.json');
|
|
||||||
define('OVERRIDE_LANG_SUFIX', false);
|
|
||||||
|
|
||||||
global $strings;
|
|
||||||
require_once('lang_functions.php');
|
|
||||||
|
|
||||||
$config = file_get_contents(CONFIG);
|
|
||||||
$config = (array) json_decode($config);
|
|
||||||
$config_langs = array_keys(get_object_vars($config['languages']));
|
|
||||||
|
|
||||||
// Set languages to do. If script is called using a language it will be used as unique.
|
|
||||||
if (isset($argv[1]) && !empty($argv[1])) {
|
|
||||||
$forcedetect = false;
|
|
||||||
define('TOTRANSLATE', true);
|
|
||||||
$languages = explode(',', $argv[1]);
|
|
||||||
} else {
|
|
||||||
$forcedetect = true;
|
|
||||||
define('TOTRANSLATE', false);
|
|
||||||
$languages = $config_langs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file_exists(ASSETSPATH)) {
|
|
||||||
mkdir(ASSETSPATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
load_langindex();
|
|
||||||
|
|
||||||
$added_langs = build_languages($languages);
|
|
||||||
|
|
||||||
if ($forcedetect) {
|
|
||||||
$new_langs = detect_languages($languages);
|
|
||||||
|
|
||||||
if (!empty($new_langs)) {
|
|
||||||
echo "\n\n\nThe following languages are going to be added\n\n\n";
|
|
||||||
$added_langs = build_languages($new_langs, $added_langs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_langs_to_config($added_langs, $config);
|
|
@ -1,29 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Script to update language packs on assets and detect new translated languages.
|
|
||||||
# ./update_lang.sh [language]
|
|
||||||
# If language is set it will only update the selected language.
|
|
||||||
# Edit lang_functions.sh LANGPACKSFOLDER variable to match your system's
|
|
||||||
#
|
|
||||||
source "functions.sh"
|
|
||||||
source "lang_functions.sh"
|
|
||||||
|
|
||||||
forceLang=$1
|
|
||||||
|
|
||||||
print_title 'Generating language from code...'
|
|
||||||
npx gulp lang
|
|
||||||
|
|
||||||
print_title 'Getting local mobile langs'
|
|
||||||
git clone --depth 1 https://github.com/moodlehq/moodle-local_moodlemobileapp.git ../../moodle-local_moodlemobileapp
|
|
||||||
|
|
||||||
if [ -z $forceLang ]; then
|
|
||||||
get_languages
|
|
||||||
php -f moodle_to_json.php
|
|
||||||
else
|
|
||||||
get_language "$forceLang"
|
|
||||||
php -f moodle_to_json.php "$forceLang"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp langindex.json ../../moodle-local_moodlemobileapp
|
|
||||||
|
|
||||||
print_ok 'All done!'
|
|
186
scripts/update_lang_functions.sh
Executable file
186
scripts/update_lang_functions.sh
Executable file
@ -0,0 +1,186 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Functions to update langpacks.
|
||||||
|
#
|
||||||
|
|
||||||
|
APPMODULENAME='local_moodlemobileapp'
|
||||||
|
|
||||||
|
TOTAL_STRINGS=0
|
||||||
|
LANGINDEX_STRINGS=0
|
||||||
|
|
||||||
|
function progressbar {
|
||||||
|
let _progress=(${1}*100/100*100)/100
|
||||||
|
let _done=(${_progress}*4)/10
|
||||||
|
let _left=40-$_done
|
||||||
|
_fill=$(printf "%${_done}s")
|
||||||
|
_empty=$(printf "%${_left}s")
|
||||||
|
bar=`printf "[${_fill// /#}${_empty// /-}] ${_progress}%%"`
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy language file
|
||||||
|
function copy_lang {
|
||||||
|
lang=$1
|
||||||
|
|
||||||
|
index_keys=`jq -r 'to_entries[] | "\"\(.key)\","' langindex.json`
|
||||||
|
index_keys=`echo $index_keys | sed 's/,*$//'`
|
||||||
|
|
||||||
|
hyphenlang=${lang/_/-}
|
||||||
|
langfilepath=$LANG_PATH/$hyphenlang.json
|
||||||
|
cp $LANGPACKS_PATH/$lang.json $langfilepath
|
||||||
|
|
||||||
|
# Merge SUFFIX file if exists.
|
||||||
|
if [ ! -z "$SUFFIX" ] && [ -f "$LANGPACKS_PATH/${lang}_${SUFFIX}.json" ]; then
|
||||||
|
suffixfilepath="$LANGPACKS_PATH/${lang}_${SUFFIX}.json"
|
||||||
|
jq --indent 4 -s --sort-keys ".[0] + .[1]" $langfilepath $suffixfilepath > /tmp/moodle-langtmp.json
|
||||||
|
mv /tmp/moodle-langtmp.json $langfilepath
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Remove strings non exiting on langindex.
|
||||||
|
query="with_entries(select([.key] | inside([$index_keys])))"
|
||||||
|
jq --indent 2 -r "$query" $langfilepath > /tmp/moodle-langtmp.json
|
||||||
|
mv /tmp/moodle-langtmp.json $langfilepath
|
||||||
|
|
||||||
|
name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json`
|
||||||
|
local=`jq -r .\"$lang\".local $LANGPACKS_PATH/languages.json`
|
||||||
|
translated=`jq -r '. | length' $langfilepath`
|
||||||
|
percentage=`echo "($translated * 100) /$LANGINDEX_STRINGS" | bc`
|
||||||
|
progressbar $percentage
|
||||||
|
echo -e "Generated $hyphenlang\t $translated of $LANGINDEX_STRINGS\t $bar ($local local)"
|
||||||
|
|
||||||
|
|
||||||
|
# Add or update language name to config.
|
||||||
|
newlang="{\"$hyphenlang\": \"$name\"}"
|
||||||
|
languages=`jq -s --sort-keys ".[0].languages + $newlang" ../moodle.config.json`
|
||||||
|
jq --indent 4 -s ".[0].languages = $languages | .[0]" ../moodle.config.json > /tmp/moodle-langtmp.json
|
||||||
|
mv /tmp/moodle-langtmp.json ../moodle.config.json
|
||||||
|
}
|
||||||
|
|
||||||
|
function detect_lang {
|
||||||
|
lang=$1
|
||||||
|
|
||||||
|
name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json`
|
||||||
|
if [ -z "$name" ] || [ "$name" == 'null' ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
hyphenlang=${lang/_/-}
|
||||||
|
if [ -f $LANG_PATH/$hyphenlang.json ]; then
|
||||||
|
# Already exists
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local=`jq -r .\"$lang\".local $LANGPACKS_PATH/languages.json`
|
||||||
|
translated=`jq -r .\"$lang\".translated $LANGPACKS_PATH/languages.json`
|
||||||
|
percentage=`echo "($translated * 100) /$TOTAL_STRINGS" | bc`
|
||||||
|
progressbar $percentage
|
||||||
|
echo -e "Checking $lang\t $translated of $TOTAL_STRINGS \t $bar ($local local)";
|
||||||
|
|
||||||
|
if [[ ( $percentage -gt 75 && $local -gt 50 ) || ( $percentage -gt 50 && $local -gt 75 ) ]] ; then
|
||||||
|
name=`jq -r .\"$lang\".name $LANGPACKS_PATH/languages.json`
|
||||||
|
echo "*** NEW LANGUAGE DETECTED $lang - $name ***"
|
||||||
|
|
||||||
|
copy_lang $lang
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_langpacks {
|
||||||
|
get_app_version
|
||||||
|
|
||||||
|
print_title 'Getting local mobile langs'
|
||||||
|
if [ -d $LANGPACKS_PATH ]; then
|
||||||
|
pushd $LANGPACKS_PATH
|
||||||
|
|
||||||
|
git checkout "langpack_$LANGVERSION"
|
||||||
|
git pull
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Cannot update language repository"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd
|
||||||
|
else
|
||||||
|
git clone --depth 1 --single-branch --branch "langpack_$LANGVERSION" https://github.com/moodlehq/moodle-local_moodlemobileapp.git $LANGPACKS_PATH
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Cannot clone language repository"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local_strings=`jq -r '.languages.local' $LANGPACKS_PATH/languages.json`
|
||||||
|
TOTAL_STRINGS=`jq -r '.languages.total' $LANGPACKS_PATH/languages.json`
|
||||||
|
LANGINDEX_STRINGS=`jq -r '. | length' langindex.json`
|
||||||
|
|
||||||
|
print_message "Total strings to translate $TOTAL_STRINGS ($local_strings local)";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Entry function to get all language files.
|
||||||
|
function get_languages {
|
||||||
|
print_title 'Copying existing languages'
|
||||||
|
# Existing languages, copy and clean the files.
|
||||||
|
langs=`jq -r '.languages | keys[]' ../moodle.config.json`
|
||||||
|
for lang in $langs; do
|
||||||
|
lang=${lang//-/_}
|
||||||
|
copy_lang $lang
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Entry function to detect new languages.
|
||||||
|
function detect_languages {
|
||||||
|
# Do not detect new langs when suffix is set.
|
||||||
|
if [ ! -z $SUFFIX ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_title "Detect new languages"
|
||||||
|
langs=`jq -r 'keys[]' $LANGPACKS_PATH/languages.json`
|
||||||
|
for lang in $langs; do
|
||||||
|
if [[ $lang = *_wp ]]; then
|
||||||
|
# Skip Workplace.
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
detect_lang $lang
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Entry function to generate translation module file.
|
||||||
|
function generate_local_module_file {
|
||||||
|
if [ ! -d "../../moodle-$APPMODULENAME" ]; then
|
||||||
|
print_error "Module $APPMODULENAME directory does not exists, skipping..."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_title "Generating $APPMODULENAME..."
|
||||||
|
|
||||||
|
module_translations=''
|
||||||
|
|
||||||
|
keys=`jq -r 'map_values(select(contains("local_moodlemobileapp"))) | keys[]' langindex.json`
|
||||||
|
for key in $keys; do
|
||||||
|
# Check if already parsed.
|
||||||
|
translation=`jq -r .\"$key\" $LANG_PATH/en.json`
|
||||||
|
if [ -z "$translation" ]; then
|
||||||
|
echo "Key $key not translated!"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
translation="${translation//\'/\\\'}"
|
||||||
|
module_translations="$module_translations\$string['$key'] = '$translation';\n";
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$module_translations" ]; then
|
||||||
|
print_error "ERROR, translations not found, you probably didn't run gulp lang!";
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e $module_translations > /tmp/translations.php
|
||||||
|
|
||||||
|
filepath="../../moodle-$APPMODULENAME/lang/en/$APPMODULENAME.php";
|
||||||
|
|
||||||
|
BEGIN_GEN=$(cat $filepath | grep -n '\/\* AUTO START \*\/' | sed 's/\(.*\):.*/\1/g')
|
||||||
|
END_GEN=$(cat $filepath | grep -n '\/\* AUTO END \*\/' | sed 's/\(.*\):.*/\1/g')
|
||||||
|
cat <(head -n $BEGIN_GEN $filepath) /tmp/translations.php <(tail -n +$END_GEN $filepath) > /tmp/translations_temp.php
|
||||||
|
mv /tmp/translations_temp.php $filepath
|
||||||
|
|
||||||
|
cp langindex.json ../../moodle-$APPMODULENAME
|
||||||
|
}
|
36
scripts/update_langpacks.sh
Executable file
36
scripts/update_langpacks.sh
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Script to update language packs on assets and detect new translated languages.
|
||||||
|
# ./update_langpacks.sh [detect]
|
||||||
|
#
|
||||||
|
# When detect is present, it will check other languages not included in moodle.config.json to be included in the build.
|
||||||
|
# It will alo generate the local module files and override the current lang.json on the src folder.
|
||||||
|
#
|
||||||
|
|
||||||
|
DIR="${BASH_SOURCE%/*}"
|
||||||
|
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
|
||||||
|
|
||||||
|
cd $DIR
|
||||||
|
|
||||||
|
source "functions.sh"
|
||||||
|
source "lang_functions.sh"
|
||||||
|
source "update_lang_functions.sh"
|
||||||
|
|
||||||
|
load_langpacks
|
||||||
|
|
||||||
|
get_languages
|
||||||
|
|
||||||
|
if [[ -z $1 ]]; then
|
||||||
|
print_ok 'All done!'
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect new languages and copy langindex to the translations folder.
|
||||||
|
|
||||||
|
detect_languages
|
||||||
|
|
||||||
|
generate_local_module_file
|
||||||
|
|
||||||
|
gulp lang-override
|
||||||
|
|
||||||
|
print_ok 'All done!'
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Activity results"
|
"pluginname": "Activity results"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Latest badges"
|
"pluginname": "Latest badges"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Blog menu"
|
"pluginname": "Blog menu"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Recent blog entries"
|
"pluginname": "Recent blog entries"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Blog tags"
|
"pluginname": "Blog tags"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Calendar"
|
"pluginname": "Calendar"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Upcoming events"
|
"pluginname": "Upcoming events"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Comments"
|
"pluginname": "Comments"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Course completion status"
|
"pluginname": "Course completion status"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Random glossary entry"
|
"pluginname": "Random glossary entry"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Learning plans"
|
"pluginname": "Learning plans"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Latest announcements"
|
"pluginname": "Latest announcements"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Online users"
|
"pluginname": "Online users"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Private files"
|
"pluginname": "Private files"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Recent activity"
|
"pluginname": "Recent activity"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Remote RSS feeds"
|
"pluginname": "Remote RSS feeds"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Self completion"
|
"pluginname": "Self completion"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"pluginname": "Tags"
|
"pluginname": "Tags"
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,4 @@
|
|||||||
"publishtoworld": "Anyone in the world",
|
"publishtoworld": "Anyone in the world",
|
||||||
"showonlyyourentries": "Show only your entries",
|
"showonlyyourentries": "Show only your entries",
|
||||||
"siteblogheading": "Site blog"
|
"siteblogheading": "Site blog"
|
||||||
}
|
}
|
||||||
|
@ -47,4 +47,4 @@
|
|||||||
"userplans": "Learning plans",
|
"userplans": "Learning plans",
|
||||||
"xcompetenciesproficientoutofy": "{{$a.x}} out of {{$a.y}} competencies are proficient",
|
"xcompetenciesproficientoutofy": "{{$a.x}} out of {{$a.y}} competencies are proficient",
|
||||||
"xcompetenciesproficientoutofyincourse": "You are proficient in {{$a.x}} out of {{$a.y}} competencies in this course."
|
"xcompetenciesproficientoutofyincourse": "You are proficient in {{$a.x}} out of {{$a.y}} competencies in this course."
|
||||||
}
|
}
|
||||||
|
@ -20,4 +20,4 @@
|
|||||||
"requirement": "Requirement",
|
"requirement": "Requirement",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"viewcoursereport": "View course report"
|
"viewcoursereport": "View course report"
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,4 @@
|
|||||||
"savemychoice": "Save my choice",
|
"savemychoice": "Save my choice",
|
||||||
"userchoosethisoption": "Users who chose this option",
|
"userchoosethisoption": "Users who chose this option",
|
||||||
"yourselection": "Your selection"
|
"yourselection": "Your selection"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"emptyfilelist": "There are no files to show.",
|
"emptyfilelist": "There are no files to show.",
|
||||||
"modulenameplural": "Folders"
|
"modulenameplural": "Folders"
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
"modulenameplural": "IMS content packages",
|
"modulenameplural": "IMS content packages",
|
||||||
"showmoduledescription": "Show description",
|
"showmoduledescription": "Show description",
|
||||||
"toc": "TOC"
|
"toc": "TOC"
|
||||||
}
|
}
|
||||||
|
@ -83,4 +83,4 @@
|
|||||||
"youranswer": "Your answer",
|
"youranswer": "Your answer",
|
||||||
"yourcurrentgradeisoutof": "Your current grade is {{$a.grade}} out of {{$a.total}}",
|
"yourcurrentgradeisoutof": "Your current grade is {{$a.grade}} out of {{$a.total}}",
|
||||||
"youshouldview": "You should answer at least: {{$a}}"
|
"youshouldview": "You should answer at least: {{$a}}"
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
"errorinvalidlaunchurl": "The launch URL is not valid.",
|
"errorinvalidlaunchurl": "The launch URL is not valid.",
|
||||||
"launchactivity": "Launch the activity",
|
"launchactivity": "Launch the activity",
|
||||||
"modulenameplural": "External tools"
|
"modulenameplural": "External tools"
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"errorwhileloadingthepage": "Error while loading the page content.",
|
"errorwhileloadingthepage": "Error while loading the page content.",
|
||||||
"modulenameplural": "Pages"
|
"modulenameplural": "Pages"
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,4 @@
|
|||||||
"responses": "Responses",
|
"responses": "Responses",
|
||||||
"results": "Results",
|
"results": "Results",
|
||||||
"surveycompletednograph": "You have completed this survey."
|
"surveycompletednograph": "You have completed this survey."
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
"accessurl": "Access the URL",
|
"accessurl": "Access the URL",
|
||||||
"modulenameplural": "URLs",
|
"modulenameplural": "URLs",
|
||||||
"pointingtourl": "URL that the resource points to."
|
"pointingtourl": "URL that the resource points to."
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,4 @@
|
|||||||
"files": "Files",
|
"files": "Files",
|
||||||
"privatefiles": "Private files",
|
"privatefiles": "Private files",
|
||||||
"sitefiles": "Site files"
|
"sitefiles": "Site files"
|
||||||
}
|
}
|
||||||
|
@ -248,4 +248,4 @@
|
|||||||
"ZA": "South Africa",
|
"ZA": "South Africa",
|
||||||
"ZM": "Zambia",
|
"ZM": "Zambia",
|
||||||
"ZW": "Zimbabwe"
|
"ZW": "Zimbabwe"
|
||||||
}
|
}
|
||||||
|
@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"application/dash_xml": "Dynamic Adaptive Streaming over HTTP (MPEG-DASH)",
|
"application/dash_xml": "Dynamic Adaptive Streaming over HTTP (MPEG-DASH)",
|
||||||
"application/epub_zip": "EPUB ebook",
|
"application/epub_zip": "EPUB ebook",
|
||||||
"application/json": "{{$a.MIMETYPE2}} text",
|
"application/json": "{{$a.MIMETYPE2}} text",
|
||||||
"application/msword": "Word document",
|
"application/msword": "Word document",
|
||||||
"application/pdf": "PDF document",
|
"application/pdf": "PDF document",
|
||||||
"application/vnd.google-apps.audio": "Google Drive audio",
|
"application/vnd.google-apps.audio": "Google Drive audio",
|
||||||
"application/vnd.google-apps.document": "Google Docs",
|
"application/vnd.google-apps.document": "Google Docs",
|
||||||
"application/vnd.google-apps.drawing": "Google Drawing",
|
"application/vnd.google-apps.drawing": "Google Drawing",
|
||||||
"application/vnd.google-apps.file": "Google Drive file",
|
"application/vnd.google-apps.file": "Google Drive file",
|
||||||
"application/vnd.google-apps.folder": "Google Drive folder",
|
"application/vnd.google-apps.folder": "Google Drive folder",
|
||||||
"application/vnd.google-apps.form": "Google Forms",
|
"application/vnd.google-apps.form": "Google Forms",
|
||||||
"application/vnd.google-apps.fusiontable": "Google Fusion Tables",
|
"application/vnd.google-apps.fusiontable": "Google Fusion Tables",
|
||||||
"application/vnd.google-apps.presentation": "Google Slides",
|
"application/vnd.google-apps.presentation": "Google Slides",
|
||||||
"application/vnd.google-apps.script": "Google Apps Scripts",
|
"application/vnd.google-apps.script": "Google Apps Scripts",
|
||||||
"application/vnd.google-apps.site": "Google Sites",
|
"application/vnd.google-apps.site": "Google Sites",
|
||||||
"application/vnd.google-apps.spreadsheet": "Google Sheets",
|
"application/vnd.google-apps.spreadsheet": "Google Sheets",
|
||||||
"application/vnd.google-apps.video": "Google Drive video",
|
"application/vnd.google-apps.video": "Google Drive video",
|
||||||
"application/vnd.moodle.backup": "Moodle backup",
|
"application/vnd.moodle.backup": "Moodle backup",
|
||||||
"application/vnd.ms-excel": "Excel spreadsheet",
|
"application/vnd.ms-excel": "Excel spreadsheet",
|
||||||
"application/vnd.ms-excel.sheet.macroEnabled.12": "Excel 2007 macro-enabled workbook",
|
"application/vnd.ms-excel.sheet.macroEnabled.12": "Excel 2007 macro-enabled workbook",
|
||||||
"application/vnd.ms-powerpoint": "Powerpoint presentation",
|
"application/vnd.ms-powerpoint": "Powerpoint presentation",
|
||||||
"application/vnd.oasis.opendocument.spreadsheet": "OpenDocument Spreadsheet",
|
"application/vnd.oasis.opendocument.spreadsheet": "OpenDocument Spreadsheet",
|
||||||
"application/vnd.oasis.opendocument.spreadsheet-template": "OpenDocument Spreadsheet template",
|
"application/vnd.oasis.opendocument.spreadsheet-template": "OpenDocument Spreadsheet template",
|
||||||
"application/vnd.oasis.opendocument.text": "OpenDocument Text document",
|
"application/vnd.oasis.opendocument.text": "OpenDocument Text document",
|
||||||
"application/vnd.oasis.opendocument.text-template": "OpenDocument Text template",
|
"application/vnd.oasis.opendocument.text-template": "OpenDocument Text template",
|
||||||
"application/vnd.oasis.opendocument.text-web": "OpenDocument Web page template",
|
"application/vnd.oasis.opendocument.text-web": "OpenDocument Web page template",
|
||||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "Powerpoint 2007 presentation",
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "Powerpoint 2007 presentation",
|
||||||
"application/vnd.openxmlformats-officedocument.presentationml.slideshow": "Powerpoint 2007 slideshow",
|
"application/vnd.openxmlformats-officedocument.presentationml.slideshow": "Powerpoint 2007 slideshow",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel 2007 spreadsheet",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Excel 2007 spreadsheet",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.template": "Excel 2007 template",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.template": "Excel 2007 template",
|
||||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word 2007 document",
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Word 2007 document",
|
||||||
"application/x-iwork-keynote-sffkey": "iWork Keynote presentation",
|
"application/x-iwork-keynote-sffkey": "iWork Keynote presentation",
|
||||||
"application/x-iwork-numbers-sffnumbers": "iWork Numbers spreadsheet",
|
"application/x-iwork-numbers-sffnumbers": "iWork Numbers spreadsheet",
|
||||||
"application/x-iwork-pages-sffpages": "iWork Pages document",
|
"application/x-iwork-pages-sffpages": "iWork Pages document",
|
||||||
"application/x-javascript": "JavaScript source",
|
"application/x-javascript": "JavaScript source",
|
||||||
"application/x-mpegURL": "HTTP Live Streaming (HLS)",
|
"application/x-mpegURL": "HTTP Live Streaming (HLS)",
|
||||||
"application/x-mspublisher": "Publisher document",
|
"application/x-mspublisher": "Publisher document",
|
||||||
"application/x-shockwave-flash": "Flash animation",
|
"application/x-shockwave-flash": "Flash animation",
|
||||||
"application/xhtml_xml": "XHTML document",
|
"application/xhtml_xml": "XHTML document",
|
||||||
"archive": "Archive ({{$a.EXT}})",
|
"archive": "Archive ({{$a.EXT}})",
|
||||||
"audio": "Audio file ({{$a.EXT}})",
|
"audio": "Audio file ({{$a.EXT}})",
|
||||||
"default": "{{$a.mimetype}}",
|
"default": "{{$a.mimetype}}",
|
||||||
"document/unknown": "File",
|
"document/unknown": "File",
|
||||||
"group:archive": "Archive files",
|
"group:archive": "Archive files",
|
||||||
"group:audio": "Audio files",
|
"group:audio": "Audio files",
|
||||||
"group:document": "Document files",
|
"group:document": "Document files",
|
||||||
"group:html_audio": "Audio files natively supported by browsers",
|
"group:html_audio": "Audio files natively supported by browsers",
|
||||||
"group:html_track": "HTML track files",
|
"group:html_track": "HTML track files",
|
||||||
"group:html_video": "Video files natively supported by browsers",
|
"group:html_video": "Video files natively supported by browsers",
|
||||||
"group:image": "Image files",
|
"group:image": "Image files",
|
||||||
"group:media_source": "Streaming media",
|
"group:media_source": "Streaming media",
|
||||||
"group:optimised_image": "Image files to be optimised, such as badges",
|
"group:optimised_image": "Image files to be optimised, such as badges",
|
||||||
"group:presentation": "Presentation files",
|
"group:presentation": "Presentation files",
|
||||||
"group:sourcecode": "Source code",
|
"group:sourcecode": "Source code",
|
||||||
"group:spreadsheet": "Spreadsheet files",
|
"group:spreadsheet": "Spreadsheet files",
|
||||||
"group:video": "Video files",
|
"group:video": "Video files",
|
||||||
"group:web_audio": "Audio files used on the web",
|
"group:web_audio": "Audio files used on the web",
|
||||||
"group:web_file": "Web files",
|
"group:web_file": "Web files",
|
||||||
"group:web_image": "Image files used on the web",
|
"group:web_image": "Image files used on the web",
|
||||||
"group:web_video": "Video files used on the web",
|
"group:web_video": "Video files used on the web",
|
||||||
"image": "Image ({{$a.MIMETYPE2}})",
|
"image": "Image ({{$a.MIMETYPE2}})",
|
||||||
"image/vnd.microsoft.icon": "Windows icon",
|
"image/vnd.microsoft.icon": "Windows icon",
|
||||||
"text/css": "Cascading Style-Sheet",
|
"text/css": "Cascading Style-Sheet",
|
||||||
"text/csv": "Comma-separated values",
|
"text/csv": "Comma-separated values",
|
||||||
"text/html": "HTML document",
|
"text/html": "HTML document",
|
||||||
"text/plain": "Text file",
|
"text/plain": "Text file",
|
||||||
"text/rtf": "RTF document",
|
"text/rtf": "RTF document",
|
||||||
"text/vtt": "Web Video Text Track",
|
"text/vtt": "Web Video Text Track",
|
||||||
"video": "Video file ({{$a.EXT}})"
|
"video": "Video file ({{$a.EXT}})"
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,4 @@
|
|||||||
"nocomments": "No comments",
|
"nocomments": "No comments",
|
||||||
"savecomment": "Save comment",
|
"savecomment": "Save comment",
|
||||||
"warningcommentsnotsent": "Couldn't sync comments. {{error}}"
|
"warningcommentsnotsent": "Couldn't sync comments. {{error}}"
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,4 @@
|
|||||||
"errornoactions": "Couldn't find an action to perform with this link.",
|
"errornoactions": "Couldn't find an action to perform with this link.",
|
||||||
"errornosites": "Couldn't find any site to handle this link.",
|
"errornosites": "Couldn't find any site to handle this link.",
|
||||||
"errorredirectothersite": "The redirect URL cannot point to a different site."
|
"errorredirectothersite": "The redirect URL cannot point to a different site."
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
|
"activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
|
||||||
"allsections": "All sections",
|
"allsections": "All sections",
|
||||||
"aria:sectionprogress": "Section progress:",
|
"aria:sectionprogress": "Section progress:",
|
||||||
"availablespace": " You currently have about {{available}} free space.",
|
"availablespace": "You currently have about {{available}} free space.",
|
||||||
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
|
"cannotdeletewhiledownloading": "Files cannot be deleted while the activity is being downloaded. Please wait for the download to finish.",
|
||||||
"completion_automatic:done": "Done:",
|
"completion_automatic:done": "Done:",
|
||||||
"completion_automatic:failed": "Failed:",
|
"completion_automatic:failed": "Failed:",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?",
|
"confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?",
|
||||||
"confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?",
|
"confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?",
|
||||||
"confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?",
|
"confirmdownloadzerosize": "You are about to start downloading.{{availableSpace}} Are you sure you want to continue?",
|
||||||
"confirmlimiteddownload": "You are not currently connected to Wi-Fi. ",
|
"confirmlimiteddownload": "You are not currently connected to Wi-Fi.",
|
||||||
"confirmpartialdownloadsize": "You are about to download <strong>at least</strong> {{size}}.{{availableSpace}} Are you sure you want to continue?",
|
"confirmpartialdownloadsize": "You are about to download <strong>at least</strong> {{size}}.{{availableSpace}} Are you sure you want to continue?",
|
||||||
"couldnotloadsectioncontent": "Could not load the section content. Please try again later.",
|
"couldnotloadsectioncontent": "Could not load the section content. Please try again later.",
|
||||||
"couldnotloadsections": "Could not load the sections. Please try again later.",
|
"couldnotloadsections": "Could not load the sections. Please try again later.",
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
"errorreadingfile": "Error reading file.",
|
"errorreadingfile": "Error reading file.",
|
||||||
"errorwhileuploading": "An error occurred during the file upload.",
|
"errorwhileuploading": "An error occurred during the file upload.",
|
||||||
"file": "File",
|
"file": "File",
|
||||||
"fileuploaded": "The file was successfully uploaded.",
|
|
||||||
"filesofthesetypes": "Accepted file types:",
|
"filesofthesetypes": "Accepted file types:",
|
||||||
|
"fileuploaded": "The file was successfully uploaded.",
|
||||||
"invalidfiletype": "{{$a}} filetype cannot be accepted.",
|
"invalidfiletype": "{{$a}} filetype cannot be accepted.",
|
||||||
"maxbytesfile": "The file {{$a.file}} is too large. The maximum size you can upload is {{$a.size}}.",
|
"maxbytesfile": "The file {{$a.file}} is too large. The maximum size you can upload is {{$a.size}}.",
|
||||||
"microphonepermissiondenied": "Permission to access the microphone has been denied.",
|
"microphonepermissiondenied": "Permission to access the microphone has been denied.",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"a11yTitle:label": "Assistive Technologies label",
|
"a11yTitle:label": "Assistive Technologies label",
|
||||||
"add": "Add",
|
|
||||||
"acceptTerms": "I accept the <a href=\":url\" target=\"_blank\">terms of use</a>",
|
"acceptTerms": "I accept the <a href=\":url\" target=\"_blank\">terms of use</a>",
|
||||||
"accountDetailsLinkText": "here",
|
"accountDetailsLinkText": "here",
|
||||||
|
"add": "Add",
|
||||||
"additionallicenseinfo": "Any additional information about the licence",
|
"additionallicenseinfo": "Any additional information about the licence",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"age": "Typical age",
|
"age": "Typical age",
|
||||||
@ -15,11 +15,11 @@
|
|||||||
"authorrole": "Author's role",
|
"authorrole": "Author's role",
|
||||||
"back": "Back",
|
"back": "Back",
|
||||||
"by": "by",
|
"by": "by",
|
||||||
"cancellabel": "Cancel",
|
|
||||||
"cancelPublishConfirmationDialogCancelButtonText": "No",
|
"cancelPublishConfirmationDialogCancelButtonText": "No",
|
||||||
"cancelPublishConfirmationDialogConfirmButtonText": "Yes",
|
"cancelPublishConfirmationDialogConfirmButtonText": "Yes",
|
||||||
"cancelPublishConfirmationDialogDescription": "Are you sure you want to cancel the sharing process?",
|
"cancelPublishConfirmationDialogDescription": "Are you sure you want to cancel the sharing process?",
|
||||||
"cancelPublishConfirmationDialogTitle": "Cancel sharing",
|
"cancelPublishConfirmationDialogTitle": "Cancel sharing",
|
||||||
|
"cancellabel": "Cancel",
|
||||||
"ccattribution": "Attribution (CC BY)",
|
"ccattribution": "Attribution (CC BY)",
|
||||||
"ccattributionnc": "Attribution-NonCommercial (CC BY-NC)",
|
"ccattributionnc": "Attribution-NonCommercial (CC BY-NC)",
|
||||||
"ccattributionncnd": "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)",
|
"ccattributionncnd": "Attribution-NonCommercial-NoDerivs (CC BY-NC-ND)",
|
||||||
@ -40,8 +40,8 @@
|
|||||||
"connectionReestablished": "Connection reestablished.",
|
"connectionReestablished": "Connection reestablished.",
|
||||||
"contactPerson": "Contact person",
|
"contactPerson": "Contact person",
|
||||||
"contentCopied": "Content is copied to the clipboard",
|
"contentCopied": "Content is copied to the clipboard",
|
||||||
"contentchanged": "This content has changed since you last used it.",
|
|
||||||
"contentLicenseTitle": "Content license info",
|
"contentLicenseTitle": "Content license info",
|
||||||
|
"contentchanged": "This content has changed since you last used it.",
|
||||||
"contenttype": "Content type",
|
"contenttype": "Content type",
|
||||||
"copyright": "Rights of use",
|
"copyright": "Rights of use",
|
||||||
"copyrightinfo": "Copyright information",
|
"copyrightinfo": "Copyright information",
|
||||||
@ -56,10 +56,10 @@
|
|||||||
"discipline:dropdownButton": "Dropdown button",
|
"discipline:dropdownButton": "Dropdown button",
|
||||||
"discipline:in": "in",
|
"discipline:in": "in",
|
||||||
"discipline:searchPlaceholder": "Type to search for disciplines",
|
"discipline:searchPlaceholder": "Type to search for disciplines",
|
||||||
"disciplines": "Disciplines",
|
|
||||||
"disciplineLabel": "Disciplines",
|
|
||||||
"disciplineDescription": "You can select multiple disciplines",
|
"disciplineDescription": "You can select multiple disciplines",
|
||||||
|
"disciplineLabel": "Disciplines",
|
||||||
"disciplineLimitReachedMessage": "You can select up to :numDisciplines disciplines",
|
"disciplineLimitReachedMessage": "You can select up to :numDisciplines disciplines",
|
||||||
|
"disciplines": "Disciplines",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"downloadtitle": "Download this content as a H5P file.",
|
"downloadtitle": "Download this content as a H5P file.",
|
||||||
"editInfoTitle": "Edit info for <strong>:title</strong>",
|
"editInfoTitle": "Edit info for <strong>:title</strong>",
|
||||||
@ -78,9 +78,9 @@
|
|||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
"iconDescription": "640x480px. If not selected content will use category icon",
|
"iconDescription": "640x480px. If not selected content will use category icon",
|
||||||
"invalidAge": "Invalid input format for Typical age. Possible input formats separated by commas: \"1, 34-45, -50, -59-\".",
|
"invalidAge": "Invalid input format for Typical age. Possible input formats separated by commas: \"1, 34-45, -50, -59-\".",
|
||||||
|
"keywordExists": "Keyword already exists!",
|
||||||
"keywords": "Keywords",
|
"keywords": "Keywords",
|
||||||
"keywordsDescription": "You can add multiple keywords separated by commas. Press \"Enter\" or \"Add\" to confirm keywords",
|
"keywordsDescription": "You can add multiple keywords separated by commas. Press \"Enter\" or \"Add\" to confirm keywords",
|
||||||
"keywordExists": "Keyword already exists!",
|
|
||||||
"keywordsExits": "Keywords already exists!",
|
"keywordsExits": "Keywords already exists!",
|
||||||
"keywordsPlaceholder": "Add keywords",
|
"keywordsPlaceholder": "Add keywords",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
@ -100,10 +100,10 @@
|
|||||||
"licenseV1": "Version 1",
|
"licenseV1": "Version 1",
|
||||||
"licenseV2": "Version 2",
|
"licenseV2": "Version 2",
|
||||||
"licenseV3": "Version 3",
|
"licenseV3": "Version 3",
|
||||||
|
"licenseVersionDescription": "Select a license version",
|
||||||
"licensee": "Licensee",
|
"licensee": "Licensee",
|
||||||
"licenseextras": "Licence extras",
|
"licenseextras": "Licence extras",
|
||||||
"licenseversion": "Licence version",
|
"licenseversion": "Licence version",
|
||||||
"licenseVersionDescription": "Select a license version",
|
|
||||||
"logoUploadText": "Organization logo or avatar",
|
"logoUploadText": "Organization logo or avatar",
|
||||||
"longDescription": "Long description",
|
"longDescription": "Long description",
|
||||||
"longDescriptionPlaceholder": "Long description of your content",
|
"longDescriptionPlaceholder": "Long description of your content",
|
||||||
@ -147,9 +147,9 @@
|
|||||||
"screenshots": "Screenshots",
|
"screenshots": "Screenshots",
|
||||||
"screenshotsDescription": "Add up to five screenshots of your content",
|
"screenshotsDescription": "Add up to five screenshots of your content",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
"shared": "Shared",
|
|
||||||
"shareFailed": "Share failed.",
|
"shareFailed": "Share failed.",
|
||||||
"shareTryAgain": "Something went wrong, please try to share again.",
|
"shareTryAgain": "Something went wrong, please try to share again.",
|
||||||
|
"shared": "Shared",
|
||||||
"sharingNote": "All content details can be edited after sharing",
|
"sharingNote": "All content details can be edited after sharing",
|
||||||
"shortDescription": "Short description",
|
"shortDescription": "Short description",
|
||||||
"shortDescriptionPlaceholder": "Short description of your content",
|
"shortDescriptionPlaceholder": "Short description of your content",
|
||||||
|
@ -19,4 +19,4 @@
|
|||||||
"questionmessage": "Question {{$a}}: {{$b}}",
|
"questionmessage": "Question {{$a}}: {{$b}}",
|
||||||
"questionno": "Question {{$a}}",
|
"questionno": "Question {{$a}}",
|
||||||
"requiresgrading": "Requires grading"
|
"requiresgrading": "Requires grading"
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
"filtersapplied": "There may be filters applied to this view. To edit filters or change the sorting order, <a href=\"{{$a}}\">open this report on your browser.</a>",
|
||||||
|
"hidecolumns": "Hide columns",
|
||||||
"modifiedby": "Modified by",
|
"modifiedby": "Modified by",
|
||||||
"reports": "Reports",
|
"reports": "Reports",
|
||||||
"filtersapplied": "There may be filters applied to this view. To edit filters or change the sorting order, <a href=\"{{$a}}\">open this report on your browser.</a>",
|
|
||||||
"reportsource": "Report source",
|
"reportsource": "Report source",
|
||||||
"timecreated": "Time created",
|
|
||||||
"showcolumns": "Show columns",
|
"showcolumns": "Show columns",
|
||||||
"hidecolumns": "Hide columns"
|
"timecreated": "Time created"
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
"cannotsyncwithoutwifi": "Your device is not connected to Wi-Fi. Connect to a Wi-Fi network or turn off Data Saver in the app settings.",
|
"cannotsyncwithoutwifi": "Your device is not connected to Wi-Fi. Connect to a Wi-Fi network or turn off Data Saver in the app settings.",
|
||||||
"changelanguage": "Change to {{$a}}",
|
"changelanguage": "Change to {{$a}}",
|
||||||
"changelanguagealert": "Changing the language will restart the app.",
|
"changelanguagealert": "Changing the language will restart the app.",
|
||||||
|
"colorscheme": "Color Scheme",
|
||||||
"colorscheme-dark": "Dark",
|
"colorscheme-dark": "Dark",
|
||||||
"colorscheme-light": "Light",
|
"colorscheme-light": "Light",
|
||||||
"colorscheme-system-notice": "System default mode will depend on your device support.",
|
|
||||||
"colorscheme-system": "System default",
|
"colorscheme-system": "System default",
|
||||||
"colorscheme": "Color Scheme",
|
"colorscheme-system-notice": "System default mode will depend on your device support.",
|
||||||
"compilationinfo": "Compilation info",
|
"compilationinfo": "Compilation info",
|
||||||
"connectwifitosync": "Connect to a Wi-Fi network or turn off Data saver to synchronise sites.",
|
|
||||||
"connecttosync": "Your device is offline. Connect to the internet to synchronise sites.",
|
"connecttosync": "Your device is offline. Connect to the internet to synchronise sites.",
|
||||||
|
"connectwifitosync": "Connect to a Wi-Fi network or turn off Data saver to synchronise sites.",
|
||||||
"copyinfo": "Copy device info on the clipboard",
|
"copyinfo": "Copy device info on the clipboard",
|
||||||
"cordovadevicemodel": "Cordova device model",
|
"cordovadevicemodel": "Cordova device model",
|
||||||
"cordovadeviceosversion": "Cordova device OS version",
|
"cordovadeviceosversion": "Cordova device OS version",
|
||||||
|
@ -8,4 +8,4 @@
|
|||||||
"replace": "Replace",
|
"replace": "Replace",
|
||||||
"sharedfiles": "Shared files",
|
"sharedfiles": "Shared files",
|
||||||
"successstorefile": "File successfully stored. Select the file to upload to your private files or use in an activity."
|
"successstorefile": "File successfully stored. Select the file to upload to your private files or use in an activity."
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,16 @@
|
|||||||
"errorareanotsupported": "This tag area is not supported by the app.",
|
"errorareanotsupported": "This tag area is not supported by the app.",
|
||||||
"inalltagcoll": "Everywhere",
|
"inalltagcoll": "Everywhere",
|
||||||
"itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
"itemstaggedwith": "{{$a.tagarea}} tagged with \"{{$a.tag}}\"",
|
||||||
"notagsfound": "No tags matching \"{{$a}}\" found",
|
|
||||||
"noresultsfor": "No results for \"{{$a}}\"",
|
"noresultsfor": "No results for \"{{$a}}\"",
|
||||||
|
"notagsfound": "No tags matching \"{{$a}}\" found",
|
||||||
"searchtags": "Search tags",
|
"searchtags": "Search tags",
|
||||||
"showingfirsttags": "Showing {{$a}} most popular tags",
|
"showingfirsttags": "Showing {{$a}} most popular tags",
|
||||||
"tag": "Tag",
|
"tag": "Tag",
|
||||||
"tagareabadgedescription": "There are {{count}} items.",
|
|
||||||
"tagarea_course": "Courses",
|
"tagarea_course": "Courses",
|
||||||
"tagarea_course_modules": "Activities and resources",
|
"tagarea_course_modules": "Activities and resources",
|
||||||
"tagarea_post": "Blog posts",
|
"tagarea_post": "Blog posts",
|
||||||
"tagarea_user": "User interests",
|
"tagarea_user": "User interests",
|
||||||
|
"tagareabadgedescription": "There are {{count}} items.",
|
||||||
"tags": "Tags",
|
"tags": "Tags",
|
||||||
"warningareasnotsupported": "Some of the tag areas are not displayed because they are not supported by the app."
|
"warningareasnotsupported": "Some of the tag areas are not displayed because they are not supported by the app."
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user