Перейти к содержимому страницы
Открыть меню
Переключить меню настроек
Открыть персональное меню
Вы не представились системе
Ваш IP-адрес будет виден всем, если вы внесёте какие-либо изменения.

Модуль:Wikidata/SisterCities

Материал из вики «Вече»

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

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 )

-- Фильтрация по датам, если включено (например, through options.onlyCurrent)
    local function getDate(snak)
        if not snak or not snak.time then return nil end
         return mw.text.split(snak.time, "T")[1]   -- "2020-04-01" из "+2020-04-01T00:00:00Z"
    end

    local today = os.date("%Y-%m-%d")

    if options.onlyCurrent == 'yes' then
        local q = statement.qualifiers or {}
        local start = q.P580 and q.P580[1] and getDate(q.P580[1])
        local stop  = q.P582 and q.P582[1] and getDate(q.P582[1])

    -- start > today → связь ещё не началась
    if start and start > today then
        return ''  -- фильтруем
    end

    -- stop < today → уже окончилась
       if stop and stop < today then
           return ''  -- фильтруем
       end
    end

	
	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;