diff --git a/Models/ThemeConfig/Conversion/AddContextToTranslations.ts b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts new file mode 100644 index 000000000..9fc3cd1e3 --- /dev/null +++ b/Models/ThemeConfig/Conversion/AddContextToTranslations.ts @@ -0,0 +1,57 @@ +import {DesugaringStep} from "./Conversion"; +import {Utils} from "../../../Utils"; +import Translations from "../../../UI/i18n/Translations"; + +export class AddContextToTranslations extends DesugaringStep { + private readonly _prefix: string; + + constructor(prefix = "") { + super("Adds a '_context' to every object that is probably a translation", ["_context"], "AddContextToTranslation"); + this._prefix = prefix; + } + + /** + * const theme = { + * layers: [ + * { + * builtin: ["abc"], + * override: { + * title:{ + * en: "Some title" + * } + * } + * } + * ] + * } + * const rewritten = new AddContextToTranslations("prefix:").convert(theme, "context").result + * const expected = { + * layers: [ + * { + * builtin: ["abc"], + * override: { + * title:{ + * _context: "prefix:context.layers.0.override.title" + * en: "Some title" + * } + * } + * } + * ] + * } + * rewritten // => expected + */ + convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[]; information?: string[] } { + + const result = Utils.WalkJson(json, (leaf, path) => { + if (typeof leaf === "object") { + return {...leaf, _context: this._prefix + context + "." + path.join(".")} + } else { + return leaf + } + }, obj => obj !== undefined && obj !== null && Translations.isProbablyATranslation(obj)) + + return { + result + }; + } + +} \ No newline at end of file diff --git a/Models/ThemeConfig/Conversion/PrepareLayer.ts b/Models/ThemeConfig/Conversion/PrepareLayer.ts index 8e4125134..069a1a190 100644 --- a/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -7,6 +7,7 @@ import SpecialVisualizations from "../../../UI/SpecialVisualizations"; import Translations from "../../../UI/i18n/Translations"; import {Translation} from "../../../UI/i18n/Translation"; import * as tagrenderingconfigmeta from "../../../assets/tagrenderingconfigmeta.json" +import {AddContextToTranslations} from "./AddContextToTranslations"; class ExpandTagRendering extends Conversion { private readonly _state: DesugaringContext; @@ -43,20 +44,23 @@ class ExpandTagRendering extends Conversion tr.group === id_) + matchingTrs = layerTrs.filter(tr => tr.group === id_ || tr.labels?.indexOf(id_) >= 0) } else { matchingTrs = layerTrs.filter(tr => tr.id === id) } + const contextWriter = new AddContextToTranslations("layers:") for (let i = 0; i < matchingTrs.length; i++) { // The matched tagRenderings are 'stolen' from another layer. This means that they must match the layer condition before being shown - const found = Utils.Clone(matchingTrs[i]); + let found : TagRenderingConfigJson = Utils.Clone(matchingTrs[i]); if (found.condition === undefined) { found.condition = layer.source.osmTags } else { found.condition = {and: [found.condition, layer.source.osmTags]} } + + found = contextWriter.convertStrict(found, layer.id+ ".tagRenderings."+found["id"]) matchingTrs[i] = found } diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index be7af4abd..d2cf44bca 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -9,7 +9,7 @@ import LayerConfig from "../LayerConfig"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; import {SubstitutedTranslation} from "../../../UI/SubstitutedTranslation"; import DependencyCalculator from "../DependencyCalculator"; -import Translations from "../../../UI/i18n/Translations"; +import {AddContextToTranslations} from "./AddContextToTranslations"; class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfigJson[]> { private readonly _state: DesugaringContext; @@ -293,60 +293,6 @@ class AddContextToTransltionsInLayout extends DesugaringStep { } -class AddContextToTranslations extends DesugaringStep { - private readonly _prefix: string; - - constructor(prefix = "") { - super("Adds a '_context' to every object that is probably a translation", ["_context"], "AddContextToTranslation"); - this._prefix = prefix; - } - - /** - * const theme = { - * layers: [ - * { - * builtin: ["abc"], - * override: { - * title:{ - * en: "Some title" - * } - * } - * } - * ] - * } - * const rewritten = new AddContextToTranslations("prefix:").convert(theme, "context").result - * const expected = { - * layers: [ - * { - * builtin: ["abc"], - * override: { - * title:{ - * _context: "prefix:context.layers.0.override.title" - * en: "Some title" - * } - * } - * } - * ] - * } - * rewritten // => expected - */ - convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[]; information?: string[] } { - - const result = Utils.WalkJson(json, (leaf, path) => { - if(typeof leaf === "object"){ - return {...leaf, _context: this._prefix + context+"."+ path.join(".")} - }else{ - return leaf - } - }, obj => obj !== undefined && obj !== null && Translations.isProbablyATranslation(obj)) - - return { - result - }; - } - -} - class ApplyOverrideAll extends DesugaringStep { constructor() { diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index 675c17f31..d54dd8318 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -262,7 +262,12 @@ export interface LayerConfigJson { * * Note that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`, * where a few very general questions are defined e.g. website, phone number, ... - * + * Furthermore, _all_ the questions of another layer can be reused with `otherlayer.*` + * If you need only a single of the tagRenderings, use `otherlayer.tagrenderingId` + * If one or more questions have a 'group' or 'label' set, select all the entries with the corresponding group or label with `otherlayer.*group` + * Remark: if a tagRendering is 'lent' from another layer, the 'source'-tags are copied and added as condition. + * If they are not wanted, remove them with an override + * * A special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox. * * At last, one can define a group of renderings where parts of all strings will be replaced by multiple other strings.