Модуль:WikidataTree

Википедия — ирекле энциклопедия мәғлүмәте

Для документации этого модуля может быть создана страница Модуль:WikidataTree/doc

local p = {}

--[[
  Функция для получения сущности (еntity) для текущей страницы
  Подробнее о сущностях см. d:Wikidata:Glossary/ru

  Принимает: строковый индентификатор (типа P18, Q42)
  Возвращает: объект таблицу, элементы которой индексируются с нуля
]]
local function getEntityFromId( id )
    if id then
        return mw.wikibase.getEntityObject( id )
    end
    return mw.wikibase.getEntityObject();
end

--[[ 
  Функция для оформления идентификатора сущности

  Принимает: строку индентификатора (типа Q42) и таблицу параметров,
  Возвращает: строку оформленного текста
]]
function p.formatEntityId( entityId, options )
	-- получение локализованного названия 
    local label = nil;
    if ( options and options.text and options.text ~= '' ) then
        label = options.text
    else
		label = mw.wikibase.label( entityId );
    end

	-- получение ссылки по идентификатору
    local link = mw.wikibase.sitelink( entityId )
    if link then
        if label then
            return '[[' .. link .. '|' .. label .. ']]'
        else
            return '[[' .. link .. ']]'
        end
    end

    if label then
        -- красная ссылка
        if not mw.title.new( label ).exists then
            return options.frame:expandTemplate{
                title = 'не переведено 5',
                args = { label, '', 'd', entityId }
            }
        end

        -- одноимённая статья уже существует - выводится текст и ссылка на ВД
        return '<span class="iw" data-title="' .. label .. '">' .. label
        	.. '<sup class="noprint">[[:d:' .. entityId .. '|[d]]]</sup>'
        	.. '</span>'
    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;
end

--[[
  Выбирает свойства по property id, дополнительно фильтруя их по рангу
  
  Копия Module:Wikidata -> selectClaims( )
]]
local function selectClaims( entity, propertySelector )
	if ( not entity ) then error( 'entity is missing'); end;
	if ( not propertySelector ) then error( 'propertySelector not specified'); end;

	local WDS = require('Module:WikidataSelectors')
	local result = WDS.filter(entity.claims, propertySelector)

    if ( not result or #result == 0 ) then
    	return nil;
    end

    return result;
end

--[[
  Выбирает свойства по property id, дополнительно фильтруя их по рангу
  
  Копия Module:Wikidata -> selectClaims( )
]]
local function selectFirstClaim( entity, propertySelector )
	local claims = selectClaims( entity, propertySelector )
	if ( claims == nil ) then
		return nil
	end

    for i, claim in ipairs(claims) do
    	return claim
	end
	
	return nil
end

local function getProperty( frame, args )
	local Wikidata = require('Module:Wikidata')

	frame.args = args
	frame.args.references = 'false'

	return Wikidata.formatProperty( frame );
end

local function itemString( frame, entityId, formatEntityId )
	return formatEntityId( entityId, { frame = frame } )
end

--[[ 
  Функция для формирования дерева по свойству для вышестоящего элменента для текущей страницы
]]
function p.parentTree( frame )
	local entity = mw.wikibase.getEntityObject()
	if not entity then
		return '';
	end
	
	local entityId = entity.id
	local list = {}
	local level = 1
	local parentProperty = 'P279'

	if frame.args.parent then
		parentProperty = string.upper( frame.args.parent )
	end

	local formatterFunction = itemString
	if frame.args[ 'value-module' ] then
		local formatter = require( 'Module:' .. frame.args[ 'value-module' ] )
		formatterFunction = formatter[ frame.args[ 'value-function' ] ]
	end

	while ( true ) do
		list[level] = formatterFunction( frame, entityId, p.formatEntityId )
		level = level + 1

		entity = getEntityFromId( entityId )
		parentClaim = selectFirstClaim( entity, parentProperty )
		if ( not parentClaim
			or not parentClaim.mainsnak
			or not parentClaim.mainsnak.datavalue
			or not parentClaim.mainsnak.datavalue.value
			or not parentClaim.mainsnak.datavalue.value[ 'numeric-id' ]
		) then
			break;
		end
		entityId = 'Q' .. parentClaim.mainsnak.datavalue.value[ 'numeric-id' ]
	end

	local out = ''
	local maxLevel = level
	local tab = frame.args[ 'tab' ]
	if tab and tab ~= '' then
		for level, value in pairs( list ) do
			out = string.rep( tab, maxLevel - level ) .. value .. '\n' .. out
		end
	else
		for level, value in pairs( list ) do
			out = value .. '\n' .. out
		end
	end

	return out
end

return p