Модуль:Wikidata — Версийн башхалла

[теллина верси][теллина верси]
Чулацам дӀабаьккхина Чулацам тӀетоьхна
Нисдарах лаьцна йаздина дац
Нисдарах лаьцна йаздина дац
МогӀа 24:
 
-- settings, may differ from project to project
local categoryLinksToEntitiesWithMissingLabel = '[[КатегориКатегория:ВикипедиВикипедия:ВикихаамашСтатьи чохьсо элементашссылками тӀена куьгэлементы доцуВикиданных хьажоргашбез йолу яззамашподписи]]';
local categoryLinksToEntitiesWithMissingLocalLanguageLabel = '[[КатегориКатегория:ВикипедиВикипедия:ВикихаамашСтатьи чохьсо элементашссылками тӀена нохчийнэлементы куьгВикиданных доцубез хьажоргашрусской йолу яззамашподписи]]';
local categoryLocalValuePresent = '[[КатегориКатегория:ВикипедиВикипедия:ВикихаамашСтатьи чохьс маьӀнашпереопределением карладаьхназначения яззамашиз Викиданных]]';
local fileDefaultSize = '267x400px';
local outputReferences = true;
МогӀа 43:
-- Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require( 'Module:Sources' )
local WDS = require( 'Module:WikidataSelectors' );
 
-- Константы
МогӀа 51 ⟶ 52 :
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement,
formatStatementDefault, formatProperty, getSourcingCircumstances,
getPropertyDatatype, getPropertyParams, loadCacheSafe, throwError, toBoolean;
 
local function copyTo( obj, target )
МогӀа 60 ⟶ 61 :
end
 
local function loadCacheSafemin( entityIdprev, next )
if ( prev == nil ) then return next;
local status, result = pcall( function() return mw.loadData( 'Module:WikidataCache/' .. entityId ) end );
ifelseif ( statusprev ==> truenext ) then return next;
else return resultprev; end
end
 
return nil;
local function max( prev, next )
if ( prev == nil ) then return next;
elseif ( prev < next ) then return next;
else return prev; end
end
 
МогӀа 169 ⟶ 174 :
local function getEntityFromId( id )
if id then
local cached = loadCacheSafe( id );
if ( cached ) then
return cached;
end
return mw.wikibase.getEntityObject( id )
end
local entity =return mw.wikibase.getEntityObject();
if ( entity ) then
local cached = loadCacheSafe( entity.id );
if ( cached ) then
return cached;
end
end
return entity;
end
 
МогӀа 239 ⟶ 233 :
-- Выбирает свойства по property id, дополнительно фильтруя их по рангу
local function selectClaims( context, options, propertySelector )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity is missing' ); end;
if ( not propertySelector ) then error( 'propertySelector not specified' ); end;
 
result = WDS.filter( options.entity.claims, propertySelector );
local WDS = require('Module:WikidataSelectors')
result = WDS.filter(options.entity.claims, propertySelector)
 
if ( not result or #result == 0 ) then
return nil;
end
 
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber( options.limit, 10 );
while #result > limit do
table.remove( result );
end
end
 
return result;
end
 
--[[
Функция для получения значения свойства элемента в заданный момент времени.
 
Принимает: контекст, элемент, временные границы, таблица ID свойства
Возвращает: таблицу соответствующих значений свойства
]]
local function getPropertyInBoundaries( context, entity, boundaries, propertyIds )
local results = {};
 
if not propertyIds or #propertyIds == 0 then
return results;
end
 
if entity.claims then
for _, propertyId in ipairs( propertyIds ) do
local filteredClaims = WDS.filter( entity.claims, propertyId .. '[rank:preferred, rank:normal]' );
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries or not propertyIds or #propertyIds == 0 then
table.insert( results, claim.mainsnak );
else
local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' );
local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' );
if ( (startBoundaries == nil or ( startBoundaries[2] <= boundaries[1]))
and (endBoundaries == nil or ( endBoundaries[1] >= boundaries[2]))) then
table.insert( results, claim.mainsnak );
end
end
end
end
 
if #results > 0 then
break;
end
end
end
 
return results;
end
 
--[[
TODO
]]
function p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId )
-- only support exact date so far, but need improvment
local left = nil;
local right = nil;
if ( statement.qualifiers and statement.qualifiers[qualifierId] ) then
for _, qualifier in pairs( statement.qualifiers[qualifierId] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier );
if ( not boundaries ) then return nil; end
left = min( left, boundaries[1] );
right = max( right, boundaries[2] );
end
end
 
if ( not left or not right ) then
return nil;
end
 
return { left, right };
end
 
--[[
TODO
]]
function p.getTimeBoundariesFromQualifiers( frame, context, statement, qualifierIds )
if not qualifierIds then
qualifierIds = { 'P582', 'P580', 'P585' };
end
for _, qualifierId in ipairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId );
if result then
return result;
end
end
 
return nil;
end
 
--[[
Функция для получения метки элемента в заданный момент времени.
 
Принимает: контекст, элемент, временные границы
Возвращает: текстовую метку элемента, язык метки
]]
function getLabelWithLang( context, options, entity, boundaries, propertyIds )
if not entity then
return nil;
end
 
local lang = mw.language.getContentLanguage();
local langCode = lang:getCode();
 
-- name from label
local label = nil;
if ( options.text and options.text ~= '' ) then
label = options.text;
else
label, langCode = entity:getLabelWithLang();
if not langCode then
return nil;
end
if not propertyIds then
propertyIds = {
'P1813[language:' .. langCode .. ']',
'P1448[language:' .. langCode .. ']',
'P1705[language:' .. langCode .. ']'
};
end
-- name from properties
local results = getPropertyInBoundaries( context, entity, boundaries, propertyIds );
for _, result in pairs( results ) do
if result.datavalue and result.datavalue.value then
if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then
label = result.datavalue.value.text;
lang = result.datavalue.value.language;
break;
elseif result.datavalue.type == 'string' then
label = result.datavalue.value;
break;
end
end
end
end
 
return label, langCode;
end
 
МогӀа 272 ⟶ 407 :
return '' --TODO error?
end
 
-- проброс всех параметров из шаблона {wikidata}
local p_frame = g_frame:getParent();
if p_frame and p_frame:getTitle() == mw.site.namespaces[10].name .. ':Wikidata' then
copyTo( p_frame.args, options );
end
 
-- improve options
МогӀа 329 ⟶ 458 :
if ( not options.entity ) then error( 'options.entity missing' ); end;
 
local claims = context.selectClaims( options, options.property );
if options.property then -- TODO: Почему тут может не быть property?
if (claims == nil) then
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return '' --TODO error?
end
МогӀа 391 ⟶ 523 :
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value["'entity-type"'] == 'item' ) then
local circumstance = 'Q' .. qualifier.datavalue.value["numeric-.id"];
if ( 'Q5727902' == circumstance ) then
circumstances.circa = true;
МогӀа 420 ⟶ 552 :
local circumstances = context.getSourcingCircumstances( statement );
 
ifoptions.qualifiers = statement.qualifiers then;
options.qualifiers = statement.qualifiers;
end
 
if ( options.references ) then
МогӀа 543 ⟶ 673 :
]]
function formatCommonsMedia( value, options )
local image = '[[File:' .. value
if options['border'] and options['border'] ~= '' then
image = image .. '|border'
end
 
local sizecaption = options['size']
if sizeoptions['caption'] and sizeoptions['caption'] ~= '' then
caption = options['caption']
if not string.match( size, 'px$' )
elseif options['description'] and options['description'] ~= '' then
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
caption = options['description']
then
end
size = size .. 'px'
if caption ~= '' then
end
caption = '<span data-wikidata-qualifier-id="P2096" style="display:block">' .. caption .. '</span>'
else
end
size = fileDefaultSize;
end
image = image .. '|' .. size
 
if not string.find( value, '[%[%]%{%}]' ) then
if options['alt'] and options['alt'] ~= '' then
image = image .. '|[[File:' .. options['alt']value
if options['border'] and options['border'] ~= '' then
end
image = image .. ']]|border'
end
local size = options['size']
if options['description'] and options['description'] ~= '' then
if size and size ~= '' then
image = image .. '<br>' .. options['description']
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
else
size = fileDefaultSize;
end
image = image .. '|' .. size
if options['alt'] and options['alt'] ~= '' then
image = image .. '|' .. options['alt']
end
image = image .. ']]'
 
if caption ~= '' then
image = image .. '<br>' .. caption
end
else
image = image .. caption
end
МогӀа 599 ⟶ 745 :
local title = options.title
if not title or title == '' then
title = value'$1'
end
title = mw.ustring.gsub( title, '$1', value )
 
return '[' .. link .. ' ' .. title .. ']'
МогӀа 636 ⟶ 783 :
end
 
if valueoptions.unit and string.match( valueoptions.unit, ~= 'http://www.wikidata.org/entity/' ) then
if options.unit ~= '-' then
out = out .. ' ' .. options.unit
end
elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then
local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' );
local unitEntity = mw.wikibase.getEntity( unitEntityId );
if unitEntity then
local writingSystemElementId = 'Q8209';
-- name from label
local langElementId = 'Q7737';
-- TODO: lang:getFallbackLanguages()
local label = getLabelWithLang( context, options, unitEntity, nil;, {
'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']',
if unitEntity.labels then
'P558[!P282][!P407]'
if unitEntity.labels[langCode] and unitEntity.labels[langCode].value then
} );
label = unitEntity.labels[langCode].value;
elseif unitEntity.labels.en and unitEntity.labels.en.value then
label = unitEntity.labels.en.value;
end
end
-- name from properties
if unitEntity.claims and unitEntity.claims.P558 then
local writingSystemElementId = 'Q8209';
local langElementId = 'Q7737';
local labelFilter = 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']';
local WDS = require( 'Module:WikidataSelectors' );
local labelClaims = WDS.filter( unitEntity.claims, labelFilter );
for r, claim in pairs( labelClaims ) do
if claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'string'
and claim.mainsnak.datavalue.value ~= '' then
label = claim.mainsnak.datavalue.value;
break;
end
end
end
out = out .. ' ' .. label;
МогӀа 699 ⟶ 828 :
if datavalue.type == 'wikibase-entityid' then
-- Entity ID
return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ), options ) end;
elseif datavalue.type == 'string' then
-- String
МогӀа 705 ⟶ 834 :
-- Media
return function( context, options, value )
if ( not options.descriptioncaption or options.descriptioncaption == '' )
and ( not options.description or options.description == '' )
and options.qualifiers and options.qualifiers.P2096 then
for i, qualifier in pairs( options.qualifiers.P2096 ) do
МогӀа 713 ⟶ 843 :
and qualifier.datavalue.value
and qualifier.datavalue.value.language == contentLanguageCode ) then
options.caption = qualifier.datavalue.value.text
options.description = qualifier.datavalue.value.text
break
МогӀа 782 ⟶ 913 :
return functionToCall( context, options, datavalue.value );
end
 
-- Небольшой словарь упрощенного отображения (TODO: надо сделать расширенный с учётом даты)
local simpleReplaces = {}
 
--[[
МогӀа 792 ⟶ 920 :
Возвращает: строку оформленного текста
]]
function formatEntityId( entityIdcontext, options, entityId )
-- получение локализованного названия
local entity = mw.wikibase.getEntity( entityId )
local label = nil;
local boundaries = nil
local labelLanguageCode = contentLanguageCode;
if ( options.text and options.text ~= '' )qualifiers then
boundaries = p.getTimeBoundariesFromQualifiers( frame, context, { qualifiers = options.qualifiers } )
label = options.text
end
else
local label, labelLanguageCode = getLabelWithLang( context, options, entity, boundaries )
if ( simpleReplaces[entityId] ) then
return simpleReplaces[entityId];
-- определение соответствующей показываемому элементу категории
local category = ''
if ( options.category ) then
local claims = WDS.filter( entity.claims, options.category );
if ( claims ) then
for _, claim in pairs( claims ) do
if ( claim.mainsnak
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'wikibase-entityid' ) then
local catEntityId = claim.mainsnak.datavalue.value.id;
local catEntity = mw.wikibase.getEntity( catEntityId );
if ( catEntity and catEntity:getSitelink() ) then
category = '[[' .. catEntity:getSitelink() .. ']]';
end
end
end
end
label, lang = mw.wikibase.getLabelWithLang( entityId );
end
 
МогӀа 810 ⟶ 954 :
if label then
if ( contentLanguageCode ~= labelLanguageCode ) then
return '[[' .. link .. '|' .. label .. ']]' .. categoryLinksToEntitiesWithMissingLocalLanguageLabel .. category;
else
return '[[' .. link .. '|' .. label .. ']]' .. category;
end
else
return '[[' .. link .. ']]' .. category;
end
end
МогӀа 822 ⟶ 966 :
-- красная ссылка
-- TODO: разобраться, почему не всегда есть options.frame
iflocal nottitle = mw.title.new( label ).exists and options.frame then;
if title and not title.exists and options.frame then
return '[[' .. label .. ']]<sup>[[:d:' .. entityId .. '|[d]]]</sup>';
return '[[' .. label .. ']]<sup>[[:d:' .. entityId .. '|[d]]]</sup>' .. category;
end
 
МогӀа 837 ⟶ 982 :
return '<span class="iw" data-title="' .. label .. '">' .. label
.. sup
.. '</span>' .. category
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. categoryLinksToEntitiesWithMissingLabel .. category;
end
 
МогӀа 866 ⟶ 1011 :
 
-- Различные уровни настройки параметров, по убыванию приоритета
local propertyParams = {};
 
-- 1. Параметры, указанные явно при вызове
if params then
local propertyParams = params;
local tplParams = mw.clone( params );
if not propertyParams then
for key, value in pairs( tplParams ) do
propertyParams = {};
if value ~= '' then
propertyParams[key] = value;
end
end
end
 
МогӀа 918 ⟶ 1068 :
 
function p.formatProperty( frame )
local plain = toBoolean( frame.args.plain, false );
local args = frame.args
 
МогӀа 929 ⟶ 1078 :
args = getPropertyParams( propertyId, datatype, args );
 
-- проброс всех параметров из шаблона {wikidata}
local p_frame = frame:getParent();
if p_frame and p_frame:getTitle() == mw.site.namespaces[10].name .. ':Wikidata' then
copyTo( p_frame.args, args );
end
 
args.plain = toBoolean( args.plain, false );
args.nocat = toBoolean( args.nocat, false );
args.references = toBoolean( args.references, true );
МогӀа 941 ⟶ 1097 :
 
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.plain then
return value
end
 
-- обработчики по типу значения
local wrapperExtraArgs = ''
if args['value-module'] and args['value-function'] and not string.find( value, '[%[%]%{%}]' ) then
local func = getUserFunction( args, 'value' );
value = func( {}, args, value );
elseif datatype == 'commonsMedia' and not string.find( value, '[%[%]%{%}]' ) then
value = formatCommonsMedia( value, args );
elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then
wrapperExtraArgs = wrapperExtraArgs .. ' data-wikidata-external-id="' .. mw.text.encode( value ).. '"';
value = formatExternalId( value, args );
elseif datatype == 'url' then
МогӀа 967 ⟶ 1125 :
and not string.match( value, '<table >]' )
and not string.match( value, '^%{%|' ) ) then
value = value .. '[[КатегориКатегория:ВикипедиВикипедия:Статьи с табличной вставкой в карточке]]'
else
-- значений с блочными тегами остаются блоком, текст встраиваем в строку
МогӀа 973 ⟶ 1131 :
or string.match( value, '<t[dhr][ >]' )
or string.match( value, '<div[ >]' ) ) then
value = '<div class="no-wikidata" ' .. wrapperExtraArgs
.. ' data-wikidata-property-id="' .. propertyId .. '">\n'
.. value .. '</div>'
else
value = '<span class="no-wikidata" ' .. wrapperExtraArgs
.. ' data-wikidata-property-id="' .. propertyId .. '">'
.. value .. '</span>'
end
МогӀа 992 ⟶ 1150 :
end
 
if ( args.plain ) then -- вызова стандартного обработчика без оформления, если передана опция plain
return frame:callParserFunction( '#property', propertyId );
end
МогӀа 1031 ⟶ 1189 :
and reference.snaks.P248[1]
and reference.snaks.P248[1].datavalue
and reference.snaks.P248[1].datavalue.value["numeric-.id"] ) then
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-.id"];
if ( preferredSources[entityId] ) then
hasPreferred = true;
МогӀа 1046 ⟶ 1204 :
and reference.snaks.P248[1]
and reference.snaks.P248[1].datavalue
and reference.snaks.P248[1].datavalue.value["numeric-.id"] ) then
local entityId = "Q" .. reference.snaks.P248[1].datavalue.value["numeric-.id"];
if ( deprecatedSources[entityId] ) then
display = false;