local p = {};
-- Configuration data
local config = require( 'Module:Родственные_проекты/config' );
-- Modules
local getArgs = require( 'Module:Arguments' ).getArgs;
local errorMsg = require( 'Module:Error' ).error;
local yesno = require( 'Module:Yesno' );
-- Variables
local modules = {};
-- Helpers
local function formatProject( frame, args, item )
local out = '';
local context = frame;
local entityId
if args.from and args.from ~= '' then
entityId = args.from
else
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
if entityId and item.sitelink then
item.value = mw.wikibase.getSitelink( entityId, item.sitelink )
elseif item[ 'module' ] and item[ 'function' ] then
if modules[ item[ 'module' ] ] == nil then
modules[ item[ 'module' ] ] = require( 'Module:' .. item[ 'module' ] );
end
context.args = item[ 'args' ] or {}
context.args.from = entityId
item.wikiValue = modules[ item[ 'module' ] ][ item[ 'function' ] ]( context );
-- add wiki prefix
if item.wikiValue ~= nil and item.wikiValue ~= '' and item.wikiPrefix ~= nil and item.wikiPrefix ~= '' then
item.wikiValue = item.wikiPrefix.. ':' .. item.wikiValue;
end
-- override value if local value does not exist
if item.value == nil or item.value == '' then
item.value = item.wikiValue;
end
end
if item.value ~= nil and item.value ~= '' then
-- replace variables
if item.title ~= nil and item.title ~= '' then
item.title = string.gsub( item.title, '%$1', item.value );
end
-- format prefix
if string.find( item.value, '^' .. item.prefix .. ':' ) ~= nil then
item.prefixFormatted = '';
else
item.prefixFormatted = item.prefix .. ':';
end
-- format image
if item.imageTemplate ~= nil and item.imageTemplate ~= '' then
item.imageFormatted = frame:expandTemplate{ title = item.imageTemplate, args = { item.value, size = config.params.itemImageSize } };
elseif item.image ~= nil and item.image ~= '' then
item.imageFormatted = '[[File:' .. item.image .. '|link=|alt=|' .. config.params.itemImageSize .. 'px]]';
end
-- format wikilink
out = out .. '[[' .. item.prefixFormatted .. item.value .. '|' .. item.title .. ']]';
end
return out;
end
local function getParamsList( frame, args, list )
local result = {};
for i, item in ipairs( list ) do
local value = args[item.id];
if value == nil or value ~= '-' then
item.localValue = value;
item.value = value;
item.formatted = formatProject( frame, args, item );
if item.formatted ~= '' then
table.insert( result, item );
end
end
end
return result;
end
-- Renders
local function renderProjects( frame, list )
local res = mw.html.create();
for i, item in ipairs( list ) do
-- wrapper
local li = res:tag( 'li' )
:addClass( config.params.tsClass .. '-item' );
-- class
local class = '';
if item.name == 'project' or item.name == 'portal' then
class = item.name .. '-box';
else
class = item.name .. '-ref';
end
-- image
if item.imageFormatted ~= nil and item.imageFormatted ~= '' then
li:tag( 'span' )
:addClass( config.params.tsClass .. '-image' )
:wikitext( item.imageFormatted );
end
-- formatted value
li:tag( 'span' )
:addClass( config.params.tsClass .. '-label' )
:addClass( class )
:wikitext( item.formatted );
end
return res;
end
local function render( frame, title, interprojects, otherprojects )
local templateStyles = frame:extensionTag{ name = 'templatestyles', args = { src = config.params.templateStyles } };
local interprojectsFormatted = renderProjects( frame, interprojects );
local otherprojectsFormatted = renderProjects( frame, otherprojects );
-- wrapper
local res = mw.html.create()
:wikitext( templateStyles );
local body = res:tag( 'div' )
:addClass( config.params.tsClass )
:addClass( config.params.bodyClass )
:attr( 'role', 'navigation' );
-- render title
if table.getn( interprojects ) > 1 and ( title == nil or title == '' ) then
title = config.title['default'];
end
if title ~= nil and title ~= '' then
body:attr( 'aria-labelledby', mw.uri.anchorEncode( title ) );
body:tag( 'div' )
:addClass( config.params.tsClass .. '-header' )
:attr( 'id', mw.uri.anchorEncode( title ) )
:wikitext( "'''" .. title .. "'''" );
else
body:attr( 'aria-label', config.title['default'] );
end
-- render inter projects
if table.getn( interprojects ) > 0 then
body:tag( 'ul' )
:node( interprojectsFormatted );
end
-- render separator
if table.getn( interprojects ) > 0 and table.getn( otherprojects ) > 0 then
body:tag( 'hr' );
end
-- render other projects
if table.getn( otherprojects ) > 0 then
body:tag( 'ul' )
:node( otherprojectsFormatted );
end
return res;
end
-- Categories
local function formatCategory( value )
return '[[Category:' .. value .. ']]';
end
local function formatCategories( frame, list )
local categories = {};
for i, item in ipairs( list ) do
local categoryItem = config.categories[ item.name ];
if categoryItem ~= nil then
if categoryItem['local'] ~= nil and item.localValue ~= nil and item.localValue ~= '' then
local category = formatCategory( categoryItem['local'] )
table.insert( categories, category );
elseif categoryItem['default'] ~= nil then
local category = formatCategory( categoryItem['default'] )
table.insert( categories, category );
end
-- when local value is equal to wikidata
if categoryItem['equal'] ~= nil
and item.localValue ~= nil and item.localValue ~= ''
and item.wikiValue ~= nil and item.wikiValue ~= ''
and item.localValue == item.wikiValue
then
local category = formatCategory( categoryItem['equal'] )
table.insert( categories, category );
end
-- when local value is not equal to wikidata
if categoryItem['not-equal'] ~= nil
and item.localValue ~= nil and item.localValue ~= ''
and item.wikiValue ~= nil and item.wikiValue ~= ''
and item.localValue ~= item.wikiValue
then
local category = formatCategory( categoryItem['not-equal'] )
table.insert( categories, category );
end
-- category for non existing pages
if categoryItem['not-exists'] ~= nil then
local page = mw.title.new( item.value, item.prefix );
if not page.exists then
local category = formatCategory( categoryItem['not-exists'] )
table.insert( categories, category );
end
end
end
end
return table.concat( categories );
end
local function renderCategories( frame, interprojects, otherprojects )
-- wrapper
local res = mw.html.create();
-- format iterprojects categories
local interprojectsCategories = formatCategories( frame, interprojects );
res:wikitext( interprojectsCategories );
-- format otherprojects categories
local otherprojectsCategories = formatCategories( frame, otherprojects );
res:wikitext( otherprojectsCategories );
-- service categories
if next( interprojects ) == nil and next( otherprojects ) == nil then
local category = formatCategory( config.categories['empty'] );
res:wikitext( category );
end
return res;
end
-- Preview
local function renderPreview( frame )
local res = mw.html.create();
if config.preview ~= nil and config.preview['empty'] ~= nil and config.preview['empty'] ~= '' then
local message = errorMsg( {
tag = 'p',
message = config.preview['empty']
} );
res:wikitext( message );
end
return res;
end;
-- Main
function p.main( frame )
local args = getArgs( frame, { wrappers = config.params.wrappers } );
local nocat = yesno( args['nocat'] );
-- title parameter
local title = '';
for i, item in ipairs( config.title.id ) do
if args[item] ~= nil and args[item] ~= '' then
title = args[item];
end
end
if title ~= nil and title ~= '' then
title = title .. ':'
end
-- get parameters list
local interprojects = getParamsList( frame, args, config['interprojects'] );
local otherprojects = getParamsList( frame, args, config['otherprojects'] );
-- wrapper
local res = mw.html.create();
-- render body
if next( interprojects ) ~= nil or next( otherprojects ) ~= nil then
local body = render( frame, title, interprojects, otherprojects );
res:node( body );
elseif config.params.showPreview and frame:preprocess( '{{REVISIONID}}' ) == '' then
local preview = renderPreview( frame );
res:node( preview );
end
-- render category list
if not nocat then
local pageTitle = mw.title.getCurrentTitle();
if pageTitle.namespace == 0 then
local categories = renderCategories( frame, interprojects, otherprojects );
res:node( categories );
end
end
return tostring( res );
end
return p;