Add check that translation for a certain theme is complete, add a few missing dutch translations

This commit is contained in:
pietervdvn 2021-10-01 04:49:19 +02:00
parent 4c2beb5334
commit 4fcd3523b7
7 changed files with 63 additions and 4 deletions

View file

@ -52,6 +52,11 @@ export interface LayoutConfigJson {
*/
language: string | string[];
/**
* Only used in 'generateLayerOverview': if present, every translation will be checked to make sure it is fully translated
*/
mustHaveLanguage?: string[]
/**
* The title, as shown in the welcome message and the more-screen
*/

View file

@ -302,6 +302,10 @@ export default class LayerConfig {
this.filters = (json.filter ?? []).map((option, i) => {
return new FilterConfig(option, `${context}.filter-[${i}]`)
});
if(json["filters"] !== undefined){
throw "Error in "+context+": use 'filter' instead of 'filters'"
}
const titleIcons = [];
const defaultIcons = [

View file

@ -81,7 +81,7 @@ export default class LayoutConfig {
this.title = new Translation(json.title, context + ".title");
this.description = new Translation(json.description, context + ".description");
this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription");
this.descriptionTail = json.descriptionTail === undefined ? new Translation({"*": ""}, context + ".descriptionTail") : new Translation(json.descriptionTail, context + ".descriptionTail");
this.descriptionTail = json.descriptionTail === undefined ? undefined : new Translation(json.descriptionTail, context + ".descriptionTail");
this.icon = json.icon;
this.socialImage = json.socialImage;
this.startZoom = json.startZoom;

View file

@ -196,4 +196,22 @@ export class Translation extends BaseUIElement {
return allIcons.filter(icon => icon != undefined)
}
static ExtractAllTranslationsFrom(object: any, context = ""): { context: string, tr: Translation }[] {
const allTranslations: { context: string, tr: Translation }[] = []
for (const key in object) {
const v = object[key]
if (v === undefined || v === null) {
continue
}
if (v instanceof Translation) {
allTranslations.push({context: context +"." + key, tr: v})
continue
}
if (typeof v === "object") {
allTranslations.push(...Translation.ExtractAllTranslationsFrom(v, context + "." + key))
continue
}
}
return allTranslations
}
}

View file

@ -461,7 +461,8 @@
"options": [
{
"question": {
"en": "Wheelchair accessible"
"en": "Wheelchair accessible",
"nl": "Rolstoel toegankelijk"
},
"osmTags": "wheelchair=yes"
}
@ -472,7 +473,8 @@
"options": [
{
"question": {
"en": "Has a changing table"
"en": "Has a changing table",
"nl": "Heeft een luiertafel"
},
"osmTags": "changing_table=yes"
}
@ -483,7 +485,8 @@
"options": [
{
"question": {
"en": "Free to use"
"en": "Free to use",
"nl": "Gratis toegankelijk"
},
"osmTags": {
"or": [

View file

@ -17,6 +17,9 @@
"nl",
"en"
],
"mustHaveLanguage": [
"nl"
],
"maintainer": "",
"icon": "./assets/themes/natuurpunt/natuurpunt.png",
"version": "0",

View file

@ -5,6 +5,8 @@ import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson";
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
import {Translation} from "../UI/i18n/Translation";
import {Utils} from "../Utils";
// This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files.
// It spits out an overview of those to be used to load them
@ -139,6 +141,16 @@ class LayerOverviewUtils {
}
}
}
const referencedLayers = Utils.NoNull(themeFile.layers.map(layer => {
if(typeof layer === "string"){
return layer
}
if(layer["builtin"] !== undefined){
return layer["builtin"]
}
return undefined
}))
themeFile.layers = themeFile.layers
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
@ -154,6 +166,20 @@ class LayerOverviewUtils {
if (theme.id !== filename) {
themeErrorCount.push("Theme ids should be the same as the name.json, but we got id: " + theme.id + " and filename " + filename + " (" + themePath + ")")
}
const neededLanguages = themeFile["mustHaveLanguage"]
if (neededLanguages !== undefined) {
console.log("Checking language requerements for ", theme.id, "as it must have", neededLanguages.join(", "))
const allTranslations = [].concat(Translation.ExtractAllTranslationsFrom(theme, theme.id), ...referencedLayers.map(layerId => Translation.ExtractAllTranslationsFrom(knownLayerIds.get(layerId), theme.id+"->"+layerId)))
for (const neededLanguage of neededLanguages) {
allTranslations
.filter(t => t.tr.translations[neededLanguage] === undefined && t.tr.translations["*"] === undefined)
.forEach(missing => {
themeErrorCount.push("The theme " + theme.id + " should be translation-complete for " + neededLanguage + ", but it lacks a translation for " + missing.context)
})
}
}
} catch (e) {
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)