Browse Source

Merge branch 'twig-wikidata'

master
parent
commit
d06a4419a9
  1. 4
      doc/TwigJS.md
  2. 1
      modulekit.php
  3. 13
      src/wikidata.js
  4. 98
      src/wikidata.php
  5. 55
      src/wikipedia.js
  6. 45
      src/wikipedia.php

4
doc/TwigJS.md

@ -76,8 +76,10 @@ Extra filters:
* filter `md5`: calculate md5 hash of a string.
* filter `enumerate`: enumerate the given list, e.g. "foo, bar, and bla". Input either an array (`[ "foo", "bar", "bla" ]|enumerate`) or a string with `;` as separator (`"foo;bar;bla"|enumerate`).
* filter `debug`: print the value (and further arguments) to the javascript console (via `console.log()`)
* filter `wikipediaAbstract`: shows the abstract of a Wikipedia article in the selected data language (or, if not available, the language which was used in input, resp. 'en' for Wikidata input). Input is either 'language:article' (e.g. 'en:Douglas Adams') or a wikidata id (e.g. 'Q42').
* filter `wikidataEntity`: returns the wikidata entity in structured form (or `null` if the entity is not cached or `false` if it does not exist). Example: https://www.wikidata.org/wiki/Special:EntityData/Q42.json
Notes:
* Variables will automatically be HTML escaped, if not the filter raw is used, e.g.: {{ tags.name|raw }}
* Variables will automatically be HTML escaped, unless the filter raw is used, e.g.: {{ tags.name|raw }}
* The templates will be rendered when the object becomes visible and when the zoom level changes.
* If you set an arbitrary value within a twig template (e.g.: {% set foo = "bar" %}), it will also be available in further templates of the same object by using (e.g.: {{ foo }}). The templates will be evaluated in the order as they are defined.

1
modulekit.php

@ -15,6 +15,7 @@ $include = array(
'src/options.php',
'src/language.php',
'src/ip-location.php',
'src/wikidata.php',
'src/wikipedia.php',
'src/ImageLoader.php',
'src/RepositoryBase.php',

13
src/wikidata.js

@ -1,3 +1,5 @@
const OverpassLayer = require('overpass-layer')
var httpGet = require('./httpGet')
var loadClash = {}
var cache = {}
@ -22,6 +24,7 @@ function wikidataLoad (id, callback) {
if (!result.entities || !result.entities[id]) {
console.log('invalid result', result)
cache[id] = false
return callback(err, null)
}
@ -39,3 +42,13 @@ function wikidataLoad (id, callback) {
module.exports = {
load: wikidataLoad
}
OverpassLayer.twig.extendFilter('wikidataEntity', function (value, param) {
if (value in cache) {
return cache[value]
}
wikidataLoad(value, () => {})
return null
})

98
src/wikidata.php

@ -0,0 +1,98 @@
<?php
$wikidataCache = array();
function wikidataLoad ($id) {
global $wikidataCache;
if (!array_key_exists($id, $wikidataCache)) {
$body = file_get_contents("https://www.wikidata.org/wiki/Special:EntityData/{$id}.json");
$body = $body ? json_decode($body, true) : false;
if (!array_key_exists('entities', $body) || !array_key_exists($id, $body['entities'])) {
return false;
}
$wikidataCache[$id] = $body['entities'][$id];
}
return $wikidataCache[$id];
}
function wikidataGetLabel ($id, $lang) {
$data = wikidataLoad($id);
if (array_key_exists($lang, $data['labels'])) {
return $data['labels'][$lang]['value'];
}
elseif (array_key_exists('en', $data['labels'])) {
return $data['labels']['en']['value'];
}
elseif (!sizeof($data['labels'])) {
return $id;
}
else {
return array_values($data['labels'])[0]['value'];
}
}
function wikidataGetValues ($id, $property) {
$data = wikidataLoad($id);
if (!array_key_exists($property, $data['claims'])) {
return [];
}
return array_map(
function ($el) {
return $el['mainsnak']['datavalue']['value'];
},
$data['claims'][$property]
);
}
function wikidataFormatDate($value, $maxPrecision = 13) {
$v = new DateTime($value['time']);
$p = min($maxPrecision, $value['precision']);
if ($p < 9) {
} else {
$formats = [
9 => 'Y',
10 => 'M Y',
11 => 'j. M Y',
12 => 'j. M Y - G:00',
13 => 'j. M Y - G:i',
14 => 'j. M Y - G:i:s',
];
return $v->format($formats[$p]);
}
}
function wikidataFormat ($id, $lang) {
$ret = '<b>' . wikidataGetLabel($id, $lang) . '</b>';
$birthDate = wikidataGetValues($id, 'P569');
$deathDate = wikidataGetValues($id, 'P570');
if (sizeof($birthDate) && sizeof($deathDate)) {
$ret .= ' (' . wikidataFormatDate($birthDate[0], 11) . ' — ' . wikidataFormatDate($deathDate[0], 11) . ')';
}
elseif (sizeof($birthDate)) {
$ret .= ' (* ' . wikidataFormatDate($birthDate[0], 11) . ')';
}
elseif (sizeof($deathDate)) {
$ret .= ' († ' . wikidataFormatDate($birthDate[0], 11) . ')';
}
$occupation = wikidataGetValues($id, 'P106');
if (sizeof($occupation)) {
$ret .= ', ' . implode(', ', array_map(
function ($value) use ($lang) {
return wikidataGetLabel($value['id'], $lang);
},
$occupation
));
}
return $ret;
}

55
src/wikipedia.js

@ -1,7 +1,11 @@
const async = require('async')
const OverpassLayer = require('overpass-layer')
var wikidata = require('./wikidata')
const displayBlock = require('./displayBlock')
var cache = {}
var getAbstractCache = {}
var loadClash = {}
function stripLinks (dom) {
@ -98,6 +102,12 @@ function get (value, callback) {
}
function getAbstract (value, callback) {
const cacheId = options.data_lang + ':' + value
if (cacheId in getAbstractCache) {
callback(null, getAbstractCache[cacheId])
return getAbstractCache[cacheId]
}
get(value,
function (err, result) {
var text = null
@ -110,11 +120,43 @@ function getAbstract (value, callback) {
text += ' <a target="_blank" href="' + result.languages[result.language] + '">' + lang('more') + '</a>'
}
getAbstractCache[cacheId] = text
callback(err, text)
}
)
}
function updateDomWikipedia (dom, callback) {
const wikipediaQueries = dom.querySelectorAll('.wikipedia')
async.each(
wikipediaQueries,
(div, done) => {
if (div.hasAttribute('data-done')) {
return done()
}
getAbstract(div.getAttribute('data-id'),
(err, result) => {
if (result) {
div.innerHTML = result
div.setAttribute('data-done', 'true')
}
done()
}
)
},
() => {
callback()
}
)
}
register_hook('show-popup', function (data, category, dom, callback) {
updateDomWikipedia(dom, () => updateDomWikipedia(dom, () => {}))
callback()
})
register_hook('show-details', function (data, category, dom, callback) {
var ob = data.object
var found = 0
@ -375,3 +417,16 @@ function getImages (tagValue, callback) {
module.exports = {
getImages: getImages
}
OverpassLayer.twig.extendFilter('wikipediaAbstract', function (value, param) {
let result
const cacheId = options.data_lang + ':' + value
if (cacheId in getAbstractCache) {
const text = getAbstractCache[cacheId]
result = '<div class="wikipedia" data-id="' + value + '" data-done="true">' + text + '</div>'
} else {
result = '<div class="wikipedia" data-id="' + value + '"><a href="https://wikidata.org/wiki/' + value + '">' + value + '</a></div>'
}
return OverpassLayer.twig.filters.raw(result)
})

45
src/wikipedia.php

@ -4,12 +4,53 @@ function ajax_wikipedia ($param) {
$wp_lang = $m[1];
$wp_page = $m[2];
}
elseif (preg_match("/^Q\d+$/", $param['page'])) {
$data = wikidataLoad($param['page']);
if (!isset($wp_lang) || !isset($wp_page)) {
if (array_key_exists('sitelinks', $data)) {
$sitelinks_ids = array_keys($data['sitelinks']);
$sitelinks_ids = array_values(array_filter($sitelinks_ids, function ($id) {
return preg_match('/wiki$/', $id) && $id !== 'commonswiki';
}));
if (array_key_exists($param['lang'] . 'wiki', $data['sitelinks'])) {
$wp_lang = $param['lang'];
$wp_url = $data['sitelinks'][$param['lang'] . 'wiki']['url'];
}
elseif (array_key_exists('enwiki', $data['sitelinks'])) {
$wp_lang = 'en';
$wp_url = $data['sitelinks']['enwiki']['url'];
}
elseif (sizeof($sitelinks_ids)) {
$id = $sitelinks_ids[0];
$wp_lang = substr($id, 0, strlen($id) - 4);
$wp_url = $data['sitelinks'][$id]['url'];
}
else {
$content = "<div><div id='mw-content-text'><div><p>" . wikidataFormat($param['page'], $param['lang']) . "</p></div></div></div>";
$url = "https://wikidata.org/wiki/{$param['page']}";
if (array_key_exists('commonswiki', $data['sitelinks'])) {
$url = $data['sitelinks']['commonswiki']['url'];
}
return array(
'content' => $content,
'languages' => [
$param['lang'] => $url,
],
'language' => $param['lang'],
);
}
}
}
if (!isset($wp_lang) || !(isset($wp_page) || isset($wp_url))) {
return false;
}
$wp_url = "https://{$wp_lang}.wikipedia.org/wiki/" . urlencode(strtr($wp_page, array(" " => "_")));
if (!isset($wp_url)) {
$wp_url = "https://{$wp_lang}.wikipedia.org/wiki/" . urlencode(strtr($wp_page, array(" " => "_")));
}
$content = file_get_contents($wp_url);

Loading…
Cancel
Save