From 1127a34f9418618586c9d81a93afe03c596f35fd Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 15 Jan 2019 19:52:04 -0500 Subject: [PATCH 1/6] Add wiki links from tag description This feature requires P31 property to be present in the data item. For an example, see https://wiki.openstreetmap.org/wiki/Item:Q104#P31 Once the bot populates them in the data items, it will automatically work for all existing keys/tags. --- data/core.yaml | 5 ++++- dist/locales/en.json | 5 ++++- modules/services/osm_wikibase.js | 16 ++++++++++++++ modules/ui/tag_reference.js | 37 ++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 213f77374..89e102deb 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -425,7 +425,10 @@ en: choose: Select feature type results: "{n} results for {search}" reference: View on OpenStreetMap Wiki - edit_reference: Edit or translate on OSM Wiki + edit_reference: Edit or translate description + wiki_reference: View wiki page + wiki_en_reference: View wiki page in English + wiki_lng_reference: View wiki page in [{lng}] back_tooltip: Change feature remove: Remove search: Search diff --git a/dist/locales/en.json b/dist/locales/en.json index 083267f94..c86262f9a 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -520,7 +520,10 @@ "choose": "Select feature type", "results": "{n} results for {search}", "reference": "View on OpenStreetMap Wiki", - "edit_reference": "Edit or translate on OSM Wiki", + "edit_reference": "Edit or translate description", + "wiki_reference": "View wiki page", + "wiki_en_reference": "View wiki page in English", + "wiki_lng_reference": "View wiki page in [{lng}]", "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", diff --git a/modules/services/osm_wikibase.js b/modules/services/osm_wikibase.js index 1ef3637d7..27b9cef3f 100644 --- a/modules/services/osm_wikibase.js +++ b/modules/services/osm_wikibase.js @@ -1,5 +1,6 @@ import _debounce from 'lodash-es/debounce'; import _forEach from 'lodash-es/forEach'; +import _ from 'lodash-es'; import { json as d3_json } from 'd3-request'; @@ -88,6 +89,21 @@ export default { }, + /** + * Convert monolingual property into a key-value object (language -> value) + * @param entity object from wikibase + * @param property string e.g. 'P31' for monolingual wiki page title + */ + monolingualClaimToValueObj: function(entity, property) { + if (!entity.claims[property]) return undefined; + return _ + .chain(entity.claims[property]) + .keyBy(function (o) { return o.mainsnak.datavalue.value.language; }) + .mapValues(function (o) { return o.mainsnak.datavalue.value.text; }) + .value(); + }, + + toSitelink: function(key, value) { var result = value ? 'Tag:' + key + '=' + value : 'Key:' + key; return result.replace(/_/g, ' ').trim(); diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index 6215250b9..d4b312a7b 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -8,6 +8,7 @@ import { utilDetect } from '../util/detect'; import { services } from '../services'; import { svgIcon } from '../svg'; import { utilQsString } from '../util'; +import _findKey from 'lodash-es/findKey'; export function uiTagReference(tag) { @@ -49,6 +50,30 @@ export function uiTagReference(tag) { title: 'Special:Redirect/file/' + image }; } + var wiki = wikibase.monolingualClaimToValueObj(entity, 'P31'); + if (wiki) { + if (wiki[langCode]) { + result.wiki = {title: wiki[langCode], text: 'wiki_reference'}; + } else { + // If exact language code was not found, try to find the first portion + // BUG: in some cases, a more elaborate fallback logic might be needed + var prefix = langCode.split('-', 2)[0]; + if (wiki[prefix]) { + result.wiki = {title: wiki[prefix], text: 'wiki_reference'}; + } else if (wiki.en) { + result.wiki = {title: wiki.en, text: 'wiki_en_reference'}; + } + } + if (result.wiki) { + result.wiki.text = t('inspector.' + result.wiki.text); + } else { + // When neither local nor EN are there, use first available + var lng = _findKey(wiki); + if (lng) { + result.wiki = {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; + } + } + } } return result; @@ -110,6 +135,18 @@ export function uiTagReference(tag) { .append('span') .text(t('inspector.edit_reference')); + if (docs.wiki) { + _body + .append('a') + .attr('class', 'tag-reference-link') + .attr('target', '_blank') + .attr('tabindex', -1) + .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.wiki.title) + .call(svgIcon('#iD-icon-out-link', 'inline')) + .append('span') + .text(docs.wiki.text); + } + // Add link to info about "good changeset comments" - #2923 if (param.key === 'comment') { _body From d724677c9f44c40ea02315ef123f2b8a77d64e16 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 15 Jan 2019 20:07:20 -0500 Subject: [PATCH 2/6] Support extracting wiki info from tag and key --- modules/services/osm_wikibase.js | 14 ++++---- modules/ui/tag_reference.js | 57 ++++++++++++++++++------------ test/spec/services/osm_wikibase.js | 21 ++++++++++- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/modules/services/osm_wikibase.js b/modules/services/osm_wikibase.js index 27b9cef3f..e17c36c0d 100644 --- a/modules/services/osm_wikibase.js +++ b/modules/services/osm_wikibase.js @@ -1,6 +1,6 @@ import _debounce from 'lodash-es/debounce'; import _forEach from 'lodash-es/forEach'; -import _ from 'lodash-es'; +import _map from 'lodash-es/map'; import { json as d3_json } from 'd3-request'; @@ -95,12 +95,12 @@ export default { * @param property string e.g. 'P31' for monolingual wiki page title */ monolingualClaimToValueObj: function(entity, property) { - if (!entity.claims[property]) return undefined; - return _ - .chain(entity.claims[property]) - .keyBy(function (o) { return o.mainsnak.datavalue.value.language; }) - .mapValues(function (o) { return o.mainsnak.datavalue.value.text; }) - .value(); + if (!entity || !entity.claims[property]) return undefined; + return entity.claims[property].reduce(function(acc, obj) { + var value = obj.mainsnak.datavalue.value; + acc[value.language] = value.text; + return acc; + }, {}); }, diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index d4b312a7b..69df2ce4d 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -50,32 +50,43 @@ export function uiTagReference(tag) { title: 'Special:Redirect/file/' + image }; } - var wiki = wikibase.monolingualClaimToValueObj(entity, 'P31'); - if (wiki) { - if (wiki[langCode]) { - result.wiki = {title: wiki[langCode], text: 'wiki_reference'}; - } else { - // If exact language code was not found, try to find the first portion - // BUG: in some cases, a more elaborate fallback logic might be needed - var prefix = langCode.split('-', 2)[0]; - if (wiki[prefix]) { - result.wiki = {title: wiki[prefix], text: 'wiki_reference'}; - } else if (wiki.en) { - result.wiki = {title: wiki.en, text: 'wiki_en_reference'}; - } - } - if (result.wiki) { - result.wiki.text = t('inspector.' + result.wiki.text); - } else { - // When neither local nor EN are there, use first available - var lng = _findKey(wiki); - if (lng) { - result.wiki = {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; - } - } + } + + // Helper method to get wiki info if a given language exists + function getWikiInfo(wiki, langCode, msg) { + if (wiki && wiki[langCode]) { + return {title: wiki[langCode], text: t(msg)}; } } + function getAnyWikiInfo(wiki) { + if (!wiki) return; + var lng = _findKey(wiki); + if (lng) { + return {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; + } + } + + // Try to get a wiki page from tag data item first, followed by the corresponding key data item. + // If neither tag nor key data item contain a wiki page in the needed language nor English, + // get the first found wiki page from either the tag or the key item. + var tagWiki = wikibase.monolingualClaimToValueObj(data.tag, 'P31'); + var keyWiki = wikibase.monolingualClaimToValueObj(data.key, 'P31'); + + // If exact language code does not exist, try to find the first part before the '-' + // BUG: in some cases, a more elaborate fallback logic might be needed + var langPrefix = langCode.split('-', 2)[0]; + + result.wiki = + getWikiInfo(tagWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(tagWiki, 'en', 'inspector.wiki_en_reference') || + getWikiInfo(keyWiki, langCode, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, langPrefix, 'inspector.wiki_reference') || + getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference') || + getAnyWikiInfo(tagWiki) || + getAnyWikiInfo(keyWiki); + return result; } diff --git a/test/spec/services/osm_wikibase.js b/test/spec/services/osm_wikibase.js index 61951abba..dc58ae094 100644 --- a/test/spec/services/osm_wikibase.js +++ b/test/spec/services/osm_wikibase.js @@ -246,7 +246,15 @@ describe('iD.serviceOsmWikibase', function () { type: 'statement', rank: 'normal' } - ] + ], + P31: [ + {mainsnak: {datavalue: {value: {text: 'Cs:Key:bridge:movable', language: 'cs'}}}}, + {mainsnak: {datavalue: {value: {text: 'DE:Key:bridge:movable', language: 'de'}}}}, + {mainsnak: {datavalue: {value: {text: 'FR:Key:bridge:movable', language: 'fr'}}}}, + {mainsnak: {datavalue: {value: {text: 'JA:Key:bridge:movable', language: 'ja'}}}}, + {mainsnak: {datavalue: {value: {text: 'Pl:Key:bridge:movable', language: 'pl'}}}}, + {mainsnak: {datavalue: {value: {text: 'Key:bridge:movable', language: 'en'}}}}, + ], }, sitelinks: { wiki: { @@ -319,4 +327,15 @@ describe('iD.serviceOsmWikibase', function () { expect(wikibase.claimToValue(keyData(), 'P6', 'de')).to.eql('Q14'); }); + it('gets monolingual value from entity as an object', function () { + expect(wikibase.monolingualClaimToValueObj(tagData(), 'P31')).to.eql({ + cs: 'Cs:Key:bridge:movable', + de: 'DE:Key:bridge:movable', + fr: 'FR:Key:bridge:movable', + ja: 'JA:Key:bridge:movable', + pl: 'Pl:Key:bridge:movable', + en: 'Key:bridge:movable', + }); + }); + }); From 9ed347534b205e9173efdd1cd6718441991d7103 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 15 Jan 2019 21:59:05 -0500 Subject: [PATCH 3/6] Remove unused import --- modules/services/osm_wikibase.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/services/osm_wikibase.js b/modules/services/osm_wikibase.js index e17c36c0d..b6f44a87b 100644 --- a/modules/services/osm_wikibase.js +++ b/modules/services/osm_wikibase.js @@ -1,6 +1,5 @@ import _debounce from 'lodash-es/debounce'; import _forEach from 'lodash-es/forEach'; -import _map from 'lodash-es/map'; import { json as d3_json } from 'd3-request'; From 2df519567d20b25eb55665c614d5344ae8de32c7 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Wed, 16 Jan 2019 14:09:22 -0500 Subject: [PATCH 4/6] updated wiki link text --- data/core.yaml | 6 +++--- dist/locales/en.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 89e102deb..e5bcd49f9 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -426,9 +426,9 @@ en: results: "{n} results for {search}" reference: View on OpenStreetMap Wiki edit_reference: Edit or translate description - wiki_reference: View wiki page - wiki_en_reference: View wiki page in English - wiki_lng_reference: View wiki page in [{lng}] + wiki_reference: View documentation + wiki_en_reference: View documentation in English + wiki_lng_reference: View documentation in [{lng}] back_tooltip: Change feature remove: Remove search: Search diff --git a/dist/locales/en.json b/dist/locales/en.json index c86262f9a..4ae6375bd 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -521,9 +521,9 @@ "results": "{n} results for {search}", "reference": "View on OpenStreetMap Wiki", "edit_reference": "Edit or translate description", - "wiki_reference": "View wiki page", - "wiki_en_reference": "View wiki page in English", - "wiki_lng_reference": "View wiki page in [{lng}]", + "wiki_reference": "View documentation", + "wiki_en_reference": "View documentation in English", + "wiki_lng_reference": "View documentation in [{lng}]", "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", From 54b4a798b1e756b88cc03532ba410a2310543454 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Wed, 16 Jan 2019 14:35:47 -0500 Subject: [PATCH 5/6] Localize language name --- data/core.yaml | 2 +- dist/locales/en.json | 2 +- modules/ui/tag_reference.js | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index e5bcd49f9..2a31ad804 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -428,7 +428,7 @@ en: edit_reference: Edit or translate description wiki_reference: View documentation wiki_en_reference: View documentation in English - wiki_lng_reference: View documentation in [{lng}] + wiki_lng_reference: View documentation in {lng} back_tooltip: Change feature remove: Remove search: Search diff --git a/dist/locales/en.json b/dist/locales/en.json index 4ae6375bd..6affc2d2a 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -523,7 +523,7 @@ "edit_reference": "Edit or translate description", "wiki_reference": "View documentation", "wiki_en_reference": "View documentation in English", - "wiki_lng_reference": "View documentation in [{lng}]", + "wiki_lng_reference": "View documentation in {lng}", "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index 69df2ce4d..136662f07 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -9,6 +9,8 @@ import { services } from '../services'; import { svgIcon } from '../svg'; import { utilQsString } from '../util'; import _findKey from 'lodash-es/findKey'; +import _find from 'lodash-es/find'; +import {dataWikipedia} from '../../data'; export function uiTagReference(tag) { @@ -59,11 +61,18 @@ export function uiTagReference(tag) { } } - function getAnyWikiInfo(wiki) { + function getAnyWikiInfo(wiki, langCode, langPrefix) { if (!wiki) return; var lng = _findKey(wiki); if (lng) { - return {title: wiki[lng], text: t('inspector.wiki_lng_reference', {lng: lng})}; + // TODO: This code should use proper CLDR country names in the current language, not this hack + var lngName = _find(dataWikipedia, function(d) { + return d[2] === langCode || d[2] === langPrefix; + }); + + return {title: wiki[lng], text: t('inspector.wiki_lng_reference', { + lng: lngName ? lngName[0] : '[' + lng + ']' + })}; } } @@ -84,8 +93,8 @@ export function uiTagReference(tag) { getWikiInfo(keyWiki, langCode, 'inspector.wiki_reference') || getWikiInfo(keyWiki, langPrefix, 'inspector.wiki_reference') || getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference') || - getAnyWikiInfo(tagWiki) || - getAnyWikiInfo(keyWiki); + getAnyWikiInfo(tagWiki, langCode, langPrefix) || + getAnyWikiInfo(keyWiki, langCode, langPrefix); return result; } From 3caf6eabed6be76b34a26ecbc2e3057e3bf1a7ec Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Wed, 16 Jan 2019 15:00:20 -0500 Subject: [PATCH 6/6] remove non local non en wiki links --- data/core.yaml | 1 - dist/locales/en.json | 1 - modules/ui/tag_reference.js | 22 +--------------------- 3 files changed, 1 insertion(+), 23 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 2a31ad804..e99c8ba5c 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -428,7 +428,6 @@ en: edit_reference: Edit or translate description wiki_reference: View documentation wiki_en_reference: View documentation in English - wiki_lng_reference: View documentation in {lng} back_tooltip: Change feature remove: Remove search: Search diff --git a/dist/locales/en.json b/dist/locales/en.json index 6affc2d2a..d76356b20 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -523,7 +523,6 @@ "edit_reference": "Edit or translate description", "wiki_reference": "View documentation", "wiki_en_reference": "View documentation in English", - "wiki_lng_reference": "View documentation in {lng}", "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", diff --git a/modules/ui/tag_reference.js b/modules/ui/tag_reference.js index 136662f07..85567be49 100644 --- a/modules/ui/tag_reference.js +++ b/modules/ui/tag_reference.js @@ -8,9 +8,6 @@ import { utilDetect } from '../util/detect'; import { services } from '../services'; import { svgIcon } from '../svg'; import { utilQsString } from '../util'; -import _findKey from 'lodash-es/findKey'; -import _find from 'lodash-es/find'; -import {dataWikipedia} from '../../data'; export function uiTagReference(tag) { @@ -61,21 +58,6 @@ export function uiTagReference(tag) { } } - function getAnyWikiInfo(wiki, langCode, langPrefix) { - if (!wiki) return; - var lng = _findKey(wiki); - if (lng) { - // TODO: This code should use proper CLDR country names in the current language, not this hack - var lngName = _find(dataWikipedia, function(d) { - return d[2] === langCode || d[2] === langPrefix; - }); - - return {title: wiki[lng], text: t('inspector.wiki_lng_reference', { - lng: lngName ? lngName[0] : '[' + lng + ']' - })}; - } - } - // Try to get a wiki page from tag data item first, followed by the corresponding key data item. // If neither tag nor key data item contain a wiki page in the needed language nor English, // get the first found wiki page from either the tag or the key item. @@ -92,9 +74,7 @@ export function uiTagReference(tag) { getWikiInfo(tagWiki, 'en', 'inspector.wiki_en_reference') || getWikiInfo(keyWiki, langCode, 'inspector.wiki_reference') || getWikiInfo(keyWiki, langPrefix, 'inspector.wiki_reference') || - getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference') || - getAnyWikiInfo(tagWiki, langCode, langPrefix) || - getAnyWikiInfo(keyWiki, langCode, langPrefix); + getWikiInfo(keyWiki, 'en', 'inspector.wiki_en_reference'); return result; }