From 3a2b163128b3d2ac7eac4c159a2af48ab83f6444 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 1 May 2022 20:56:16 +0200 Subject: [PATCH] Also load wikipedia articla from 'wikipedia' tag if no wikidata is given, fixes #780 --- Logic/Web/Wikipedia.ts | 17 +++++++ UI/SpecialVisualizations.ts | 17 ++++--- UI/Wikipedia/WikipediaBox.ts | 74 +++++++++++++++++++++++------ assets/tagRenderings/questions.json | 7 +++ 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/Logic/Web/Wikipedia.ts b/Logic/Web/Wikipedia.ts index 66d848b2e6..0988ba3f8f 100644 --- a/Logic/Web/Wikipedia.ts +++ b/Logic/Web/Wikipedia.ts @@ -51,6 +51,23 @@ export default class Wikipedia { public static getPageUrl(options: {language?: "en" | string, pageName: string}): string{ return `https://${options.language ?? "en"}.wikipedia.org/wiki/` + options.pageName } + + /** + * Tries to extract the language and article name from the given string + * + * Wikipedia.extractLanguageAndName("qsdf") // => undefined + * Wikipedia.extractLanguageAndName("nl:Warandeputten") // => {lang: "nl", article: "Warandeputten"} + */ + public static extractLanguageAndName(input: string):{language: string, pageName: string} { + const matched = input.match("([^:]+):(.*)") + if(matched === undefined || matched === null){ + return undefined + } + const [_ , language, pageName] = matched + return { + language, pageName + } + } public static async GetArticleAsync(options: { pageName: string, diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 23a678bebc..cf93598e9e 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -244,20 +244,25 @@ export default class SpecialVisualizations { args: [ { name: "keyToShowWikipediaFor", - doc: "Use the wikidata entry from this key to show the wikipedia article for", - defaultValue: "wikidata" + doc: "Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used", + defaultValue: "wikidata;wikipedia" } ], example: "`{wikipedia()}` is a basic example, `{wikipedia(name:etymology:wikidata)}` to show the wikipedia page of whom the feature was named after. Also remember that these can be styled, e.g. `{wikipedia():max-height: 10rem}` to limit the height", - constr: (_, tagsSource, args) => - new VariableUiElement( - tagsSource.map(tags => tags[args[0]]) + constr: (_, tagsSource, args) => { + const keys = args[0].split(";").map(k => k.trim()) + return new VariableUiElement( + tagsSource.map(tags => { + const key = keys.find(k => tags[k] !== undefined && tags[k] !== "") + return tags[key]; + }) .map(wikidata => { const wikidatas: string[] = Utils.NoEmpty(wikidata?.split(";")?.map(wd => wd.trim()) ?? []) return new WikipediaBox(wikidatas) }) - ) + ); + } }, { diff --git a/UI/Wikipedia/WikipediaBox.ts b/UI/Wikipedia/WikipediaBox.ts index e096ceee74..fa55376c5d 100644 --- a/UI/Wikipedia/WikipediaBox.ts +++ b/UI/Wikipedia/WikipediaBox.ts @@ -27,23 +27,23 @@ export default class WikipediaBox extends Combine { const mainContents = [] - const pages = wikidataIds.map(wdId => WikipediaBox.createLinkedContent(wdId.trim())) + const pages = wikidataIds.map(entry => WikipediaBox.createLinkedContent(entry.trim())) if (wikidataIds.length == 1) { const page = pages[0] mainContents.push( new Combine([ new Combine([ - Svg.wikipedia_svg().SetStyle("width: 1.5rem").SetClass("inline-block mr-3"), + Svg.wikipedia_ui().SetStyle("width: 1.5rem").SetClass("inline-block mr-3"), page.titleElement]).SetClass("flex"), page.linkElement ]).SetClass("flex justify-between align-middle"), ) - mainContents.push(page.contents) + mainContents.push(page.contents.SetClass("overflow-auto normal-background rounded-lg")) } else if (wikidataIds.length > 1) { const tabbed = new TabbedComponent( pages.map(page => { - const contents = page.contents.SetClass("block").SetStyle("max-height: inherit; height: inherit; padding-bottom: 3.3rem") + const contents = page.contents.SetClass("overflow-auto normal-background rounded-lg block").SetStyle("max-height: inherit; height: inherit; padding-bottom: 3.3rem") return { header: page.titleElement.SetClass("pl-2 pr-2"), content: new Combine([ @@ -74,7 +74,53 @@ export default class WikipediaBox extends Combine { .SetStyle("max-height: inherit") } - private static createLinkedContent(wikidataId: string): { + private static createLinkedContent(entry: string): { + titleElement: BaseUIElement, + contents: BaseUIElement, + linkElement: BaseUIElement + } { + if (entry.match("[qQ][0-9]+")) { + return WikipediaBox.createWikidatabox(entry) + } else { + console.log("Creating wikipedia box for ", entry) + return WikipediaBox.createWikipediabox(entry) + } + } + + /** + * Given a ':'-string, constructs the wikipedia article + * @param wikipediaArticle + * @private + */ + private static createWikipediabox(wikipediaArticle: string): { + titleElement: BaseUIElement, + contents: BaseUIElement, + linkElement: BaseUIElement + } { + const wp = Translations.t.general.wikipedia; + + const article = Wikipedia.extractLanguageAndName(wikipediaArticle) + if (article === undefined) { + return { + titleElement: undefined, + contents: wp.noWikipediaPage, + linkElement: undefined + } + } + const url = Wikipedia.getPageUrl(article) // `https://${language}.wikipedia.org/wiki/${pagetitle}` + const linkElement = new Link(Svg.pop_out_svg().SetStyle("width: 1.2rem").SetClass("block "), url, true) .SetClass("flex items-center enable-links") + + return { + titleElement: new Title(article.pageName, 3), + contents: WikipediaBox.createContents(article.pageName, article.language), + linkElement + } + } + + /** + * Given a `Q1234`, constructs a wikipedia box or wikidata box + */ + private static createWikidatabox(wikidataId: string): { titleElement: BaseUIElement, contents: BaseUIElement, linkElement: BaseUIElement @@ -130,11 +176,11 @@ export default class WikipediaBox extends Combine { } const [pagetitle, language, wd] = <[string, string, WikidataResponse]>status - return WikipediaBox.createContents(pagetitle, language, wd) + const quickFacts = WikidataPreviewBox.QuickFacts(wd); + return WikipediaBox.createContents(pagetitle, language, quickFacts) }) - ).SetClass("overflow-auto normal-background rounded-lg") - + ) const titleElement = new VariableUiElement(wikiLink.map(state => { if (typeof state !== "string") { @@ -145,8 +191,7 @@ export default class WikipediaBox extends Combine { } return new Title(pagetitle, 3) } - //return new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2) - return new Link(new Title(wikidataId, 3), "https://www.wikidata.org/wiki/"+wikidataId, true) + return new Link(new Title(wikidataId, 3), "https://www.wikidata.org/wiki/" + wikidataId, true) })) @@ -178,7 +223,7 @@ export default class WikipediaBox extends Combine { /** * Returns the actual content in a scrollable way */ - private static createContents(pagename: string, language: string, wikidata: WikidataResponse): BaseUIElement { + private static createContents(pagename: string, language: string, topBar?: BaseUIElement): BaseUIElement { const wpOptions = { pageName: pagename, language: language, @@ -186,7 +231,6 @@ export default class WikipediaBox extends Combine { } const htmlContent = Wikipedia.GetArticle(wpOptions) const wp = Translations.t.general.wikipedia - const quickFacts = WikidataPreviewBox.QuickFacts(wikidata); const contents: UIEventSource = htmlContent.map(htmlContent => { if (htmlContent === undefined) { // Still loading @@ -194,11 +238,11 @@ export default class WikipediaBox extends Combine { } if (htmlContent["success"] !== undefined) { let content: BaseUIElement = new FixedUiElement(htmlContent["success"]); - if(WikipediaBox.configuration.addHeader){ + if (WikipediaBox.configuration.addHeader) { content = new Combine( [ new Paragraph( - new Link(wp.fromWikipedia, Wikipedia.getPageUrl(wpOptions), true), + new Link(wp.fromWikipedia, Wikipedia.getPageUrl(wpOptions), true), ), new Paragraph( content @@ -217,7 +261,7 @@ export default class WikipediaBox extends Combine { }) return new Combine([ - quickFacts?.SetClass("border-2 border-grey rounded-lg m-1 mb-0"), + topBar?.SetClass("border-2 border-grey rounded-lg m-1 mb-0"), new VariableUiElement(contents) .SetClass("block pl-6 pt-2")]) } diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index cb877b6080..f3b9f640f6 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -33,6 +33,13 @@ "zh_Hans": "在Wikidata上对应的实体是什么?" }, "mappings": [ + { + "if": "wikipedia~*", + "then": { + "*": "{wikipedia():max-height:25rem}" + }, + "hideInAnswer": true + }, { "if": "wikidata=", "then": {