Модуль:Wikidata/SisterCities

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация

Данный шаблон добавляет список городов-побратимов из Викиданных. Список заранее оформлен в несколько колонок с использованием css-класса autocolumns. В основном, используется при помощи шаблона {{Wikidata/SisterCities}}.

local p = {};
local flags = require( 'Module:Wikidata/Flags' );

local delink

function p.formatSisterCitiesProperty( context, options )
	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 missing' ); end;

    local claims = context.selectClaims( options, options.property );
    if claims == nil then
        return ''; --TODO error?
    end

	local cityNames = {};
    for i, claim in ipairs( claims ) do
    	if claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then
    		cityNames[ claim.id ] = mw.wikibase.label( claim.mainsnak.datavalue.value.id );
    	else
    		cityNames[ claim.id ] = '(none)';
    	end
	end

	local comparator = function( c1, c2 )
		local n1 = cityNames[ c1.id ] or '';
		local n2 = cityNames[ c2.id ] or '';
		return n1 < n2;
	end
	table.sort( claims, comparator );

    -- Обход всех заявлений утверждения и с накоплением оформленых предпочтительных 
    -- заявлений в таблице
    local formattedClaims = {};

    for i, claim in ipairs( claims ) do
        local formattedStatement = context.formatStatement( options, claim );
        -- здесь может вернуться либо оформленный текст заявления
        -- либо строка ошибки nil похоже никогда не возвращается
        if formattedStatement then
            formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' ..
            	string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' ..
            	formattedStatement .. '</span>';
            table.insert( formattedClaims, formattedStatement );
        end
    end

	-- создание текстовой строки со списком оформленых заявлений из таблицы  
    local out = mw.text.listToText( formattedClaims, '\n* ', '\n* ' );
    if out ~= '' then
    	out = '* ' .. out;
	    if options.before then
	    	out = options.before .. out;
		end
	    if options.after then
	    	out = out .. options.after;
		end
	end

    return out
end

function findCountryStatements( placeId )
	local countryStatements = {};

	for _, countryStatement in pairs( mw.wikibase.getBestStatements( placeId, 'P17' ) ) do
		if countryStatement and
			countryStatement.mainsnak and
			countryStatement.mainsnak.datavalue and
			countryStatement.mainsnak.datavalue.value and
			not ( countryStatement.qualifiers and countryStatement.qualifiers.P582 )
		then
			table.insert( countryStatements, countryStatement );
		end
	end
	return countryStatements;
end

local flagsWikitextCache = {};
local countriesWikitextCache = {};

function p.formatSisterCityClaim( context, options, statement )
	local result = '';
	if not statement or statement.mainsnak.snaktype ~= 'value' then
		return result;
	end

	local countryStatements = findCountryStatements( statement.mainsnak.datavalue.value.id );
	local flagImages = {};
	for _, countryStatement in pairs( countryStatements ) do
		local countryId = countryStatement.mainsnak.datavalue.value.id;
		local flagImage = flagsWikitextCache[ countryId ];
		if flagImage == nil then
			flagImage = flags.getFlag( context, countryId, os.time() * 1000);
			flagsWikitextCache[ countryId ] = flagImage;
		end
		if flagImage then
			table.insert( flagImages, flagImage );
		end
	end

	if #flagImages then
		local flagText = mw.text.listToText( flagImages, '&nbsp;/&nbsp;', '&nbsp;/&nbsp;' )
		result = result .. flagText .. ( flagText ~= '' and '&nbsp;' or '' );
	end

	result = result .. context.formatSnak( options, statement.mainsnak, {} );

	local countryLinks = {};
	for _, countryStatement in pairs( countryStatements ) do
		local countryId = countryStatement.mainsnak.datavalue.value.id;
		local countryText = countriesWikitextCache[ countryId ];
		if countryText == nil then
			countryText = context.formatSnak( {}, countryStatement.mainsnak, {} );
			countriesWikitextCache[ countryId ] = countryText;
		end
		if countryText then
			table.insert( countryLinks, countryText );
		end
	end

	if #countryLinks then
		result = result .. ', ' .. mw.text.listToText( countryLinks, ' / ', ' / ' );
	end

	if statement.qualifiers and statement.qualifiers.P580 then
		if not delink then
			-- [[Module:Delink]] contains require( 'strict' ), [[Module:Sources]] errors out with it
			delink = function( text )
				return mw.getCurrentFrame():expandTemplate{
					title = 'Delink',
					args = { text },
				}
			end
		end
		local snak = context.formatSnak( options, statement.qualifiers.P580[ 1 ] )
		result = result .. ' (' .. delink( snak ) .. ')';
	end

	if options.references then
		result = result .. context.formatRefs( options, statement );
	end
	
	return result;
end

return p;