forked from MapComplete/MapComplete
		
	Add check that translation for a certain theme is complete, add a few missing dutch translations
This commit is contained in:
		
							parent
							
								
									4c2beb5334
								
							
						
					
					
						commit
						4fcd3523b7
					
				
					 7 changed files with 63 additions and 4 deletions
				
			
		|  | @ -52,6 +52,11 @@ export interface LayoutConfigJson { | ||||||
|      */ |      */ | ||||||
|     language: string | string[]; |     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 |      * The title, as shown in the welcome message and the more-screen | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  | @ -302,6 +302,10 @@ export default class LayerConfig { | ||||||
|         this.filters = (json.filter ?? []).map((option, i) => { |         this.filters = (json.filter ?? []).map((option, i) => { | ||||||
|             return new FilterConfig(option, `${context}.filter-[${i}]`) |             return new FilterConfig(option, `${context}.filter-[${i}]`) | ||||||
|         }); |         }); | ||||||
|  |         | ||||||
|  |        if(json["filters"] !== undefined){ | ||||||
|  |            throw "Error in "+context+": use 'filter' instead of 'filters'" | ||||||
|  |        } | ||||||
| 
 | 
 | ||||||
|         const titleIcons = []; |         const titleIcons = []; | ||||||
|         const defaultIcons = [ |         const defaultIcons = [ | ||||||
|  |  | ||||||
|  | @ -81,7 +81,7 @@ export default class LayoutConfig { | ||||||
|         this.title = new Translation(json.title, context + ".title"); |         this.title = new Translation(json.title, context + ".title"); | ||||||
|         this.description = new Translation(json.description, context + ".description"); |         this.description = new Translation(json.description, context + ".description"); | ||||||
|         this.shortDescription = json.shortDescription === undefined ? this.description.FirstSentence() : new Translation(json.shortDescription, context + ".shortdescription"); |         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.icon = json.icon; | ||||||
|         this.socialImage = json.socialImage; |         this.socialImage = json.socialImage; | ||||||
|         this.startZoom = json.startZoom; |         this.startZoom = json.startZoom; | ||||||
|  |  | ||||||
|  | @ -196,4 +196,22 @@ export class Translation extends BaseUIElement { | ||||||
|         return allIcons.filter(icon => icon != undefined) |         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 | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -461,7 +461,8 @@ | ||||||
|             "options": [ |             "options": [ | ||||||
|                 { |                 { | ||||||
|                     "question": { |                     "question": { | ||||||
|                         "en": "Wheelchair accessible" |                         "en": "Wheelchair accessible", | ||||||
|  |                         "nl": "Rolstoel toegankelijk" | ||||||
|                     }, |                     }, | ||||||
|                     "osmTags": "wheelchair=yes" |                     "osmTags": "wheelchair=yes" | ||||||
|                 } |                 } | ||||||
|  | @ -472,7 +473,8 @@ | ||||||
|             "options": [ |             "options": [ | ||||||
|                 { |                 { | ||||||
|                     "question": { |                     "question": { | ||||||
|                         "en": "Has a changing table" |                         "en": "Has a changing table", | ||||||
|  |                         "nl": "Heeft een luiertafel" | ||||||
|                     }, |                     }, | ||||||
|                     "osmTags": "changing_table=yes" |                     "osmTags": "changing_table=yes" | ||||||
|                 } |                 } | ||||||
|  | @ -483,7 +485,8 @@ | ||||||
|             "options": [ |             "options": [ | ||||||
|                 { |                 { | ||||||
|                     "question": { |                     "question": { | ||||||
|                         "en": "Free to use" |                         "en": "Free to use", | ||||||
|  |                         "nl": "Gratis toegankelijk" | ||||||
|                     }, |                     }, | ||||||
|                     "osmTags": { |                     "osmTags": { | ||||||
|                         "or": [ |                         "or": [ | ||||||
|  |  | ||||||
|  | @ -17,6 +17,9 @@ | ||||||
|     "nl", |     "nl", | ||||||
|     "en" |     "en" | ||||||
|   ], |   ], | ||||||
|  |   "mustHaveLanguage": [ | ||||||
|  |     "nl" | ||||||
|  |   ], | ||||||
|   "maintainer": "", |   "maintainer": "", | ||||||
|   "icon": "./assets/themes/natuurpunt/natuurpunt.png", |   "icon": "./assets/themes/natuurpunt/natuurpunt.png", | ||||||
|   "version": "0", |   "version": "0", | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson"; | ||||||
| import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; | import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; | ||||||
| import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; | import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; | ||||||
| import LayerConfig from "../Models/ThemeConfig/LayerConfig"; | 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.
 | // 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
 | // 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 |             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
 |                 .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) { |                 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 + ")") |                     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) { |             } catch (e) { | ||||||
|                 themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e) |                 themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue