Modul':External links
local data = require( 'Module:External links/data' ) -- Localizable part -- Please note that labels for websites and catalogs are taken from Wikidata (i.e. Wikidata label)
-- Feel free to correct labels and categories here local categoryTemplateEmpty = 'RUWIKI:Šablon «Irdtarkendused» om tühj' local categoryCustomColor = 'RUWIKI:Šablon «Irdtarkendused» eriliženke mujunke' local templateLink = 'Внешние ссылки' local templateTitle = 'Ссылки на внешние ресурсы' local wikidataLink = 'Перейти к элементу РУВИКИ.Данных' local refLabels = { Q1406 = 'Windows', Q10677 = 'PS1', Q10680 = 'PS2', Q10683 = 'PS3', Q16338 = 'ПК', Q135321 = 'FDS', Q170323 = 'DS', Q170325 = 'PSP', Q172742 = 'NES', Q182172 = 'GameCube', Q183259 = 'SNES', Q184839 = 'N64', Q188642 = 'GBA', Q188808 = 'PS Vita', Q203597 = '3DS', Q5014725 = 'PS4', Q19610114 = 'Switch', Q63184502 = 'PS5', }
-- The language codes that should always be displayed even if they have normal rank and a claim with another language and preferred rank exists local preferredLanguage = 'Q7737' -- russian
local templateColorName = 'цвет' -- Some projects have "named" colors, defined by templates local function colorByTitle( frame, colorTitle ) local templateName = 'Цвет/' .. colorTitle local templateTitle = mw.title.makeTitle( 'Template', templateName ) if not templateTitle or not templateTitle.exists then return false end return frame:expandTemplate{ title = templateName } end
-- Non-localizable part (not need to localize ) local moduleNavbox = require( 'Module:Navbox' ) local moduleLanguages -- accessed if necessary
local propertyQualifiers = { P553 = { P554 = 'url', }, P1343 = { P805 = 'iw', P248 = 'iw', -- deprecated, fallback for P805 P953 = 'url', P854 = 'url', -- deprecated, fallback for P953 }, }
local p = {}
-- Helper functions local function replace( str, pattern, repl )
pattern = mw.ustring.gsub( pattern, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1" ) -- escape pattern repl = mw.ustring.gsub( repl, "[%%]", "%%%%" ) -- escape replacement repl = mw.ustring.gsub( repl, " ", "%%%%20" ) -- escape replacement return mw.ustring.gsub( str, pattern, repl )
end
-- Render functions
local function renderList( elements )
if #elements == 0 then
return
end
return '*' .. table.concat( elements , '\n*' ) .. '\n' end
local function renderLabel( params ) if type( params ) == 'string' then return params end
local qid = params[ 1 ] local default = params[ 2 ]
if #params >= 3 then local label = params[ 3 ] local link = mw.wikibase.sitelink( qid ) if link then return '' .. label .. '' end local title = mw.wikibase.label( qid ) or default if title ~= label then return '' .. label .. '' end end
return mw.wikibase.label( qid ) or default end
local function renderLink( resourceData, label, formatter, idAsLabel ) if resourceData.itemId == nil then return '' .. label .. ': Не удаётся определить элемент' end
local link if not formatter then link = resourceData.itemId idAsLabel = false elseif type( formatter ) == 'string' then link = replace( formatter, '$1', resourceData.itemId ) elseif type ( formatter ) == 'function' then link = formatter( resourceData.itemId, resourceData.qualifiers ) end
-- "Label: ID" without link if not link or link == then return renderLabel( label ) .. ': ' .. resourceData.itemId end
local resourceLabel = resourceData.itemId if not idAsLabel then resourceLabel = renderLabel( label ) end
local linkFirstChar = mw.ustring.sub( link, 1, 1 ) if linkFirstChar == ':' then return '' .. resourceLabel .. '' end
return '[' .. link .. ' ' .. resourceLabel .. ']' end
local function renderLangRef( languages ) local result = if languages and #languages > 0 then if moduleLanguages ~= false then -- not false, but maybe nil if mw.title.makeTitle( 'Module', 'Languages' ).exists and mw.title.makeTitle( 'Module', 'Languages/data' ).exists and mw.title.makeTitle( 'Module', 'Wikidata/Language-codes' ).exists then moduleLanguages = require( 'Module:Languages' ) else moduleLanguages = false end end
if moduleLanguages then for langIndex, language in pairs( languages ) do result = result .. ' ' .. moduleLanguages.getWikidataRefHtml( language ) end end end
return result end
local function renderRefs( refs ) local result = if refs and #refs > 0 then for _, ref in ipairs( refs ) do result = result .. ' (' .. ref .. ')' end end
return result end
local function renderLinkWithRef( resourceData, label, formatter, idAsLabel ) local link = renderLink( resourceData, label, formatter, idAsLabel ) if link ~= then link = link .. renderLangRef( resourceData.languages ) link = link .. renderRefs( resourceData.refs ) end return link end
-- Data fetching functions
local function getValueFromSnak( snak )
if not snak.datavalue then
return
end
if snak.datavalue.type == 'wikibase-entityid' then
return snak.datavalue.value.id
end
if snak.datavalue.type == 'monolingualtext' then
return snak.datavalue.value.text
end
return snak.datavalue.value
end
local function getQualifierSingleValue( statement, qualifierName ) if not statement or not statement.qualifiers or not statement.qualifiers[ qualifierName ] then return nil end
for qualifierIndex, qualifier in pairs( statement.qualifiers[ qualifierName ] ) do if qualifier.datavalue and qualifier.datavalue.type and qualifier.datavalue.value then return getValueFromSnak( qualifier ) end end
return nil end
local function getQualifierValues( statement ) if not statement or not statement.qualifiers then return {} end
local result = {}
for qualifierName, qualifiers in pairs( statement.qualifiers ) do for _, qualifier in pairs( qualifiers ) do if qualifier.datavalue and qualifier.datavalue.type and qualifier.datavalue.value then if not result[ qualifierName ] then result[ qualifierName ] = {} end table.insert( result[ qualifierName ], getValueFromSnak( qualifier ) ) end end end
return result end
local function contains( tableStructure, value ) if not tableStructure or not value then return true end for index, line in pairs( tableStructure ) do if line == value then return true end end return false end
local function filterByRank( resourceDatas ) -- itemId, languages. rank = rank
local hasPreffered = false for index, resourceData in pairs( resourceDatas ) do if resourceData.rank == 'preferred' then hasPreffered = true end end
if not hasPreffered then return resourceDatas end
local result = {} for index, resourceData in pairs( resourceDatas ) do if resourceData.rank == 'preferred' or contains( resourceData.languages, preferredLanguage ) then table.insert( result, resourceData ) end end
return result end
local function getLinkData( statement, qualifier, project ) local rank = statement.rank or 'normal' if rank == 'deprecated' or not statement.mainsnak.datavalue then return nil end
local itemId if qualifier then itemId = getQualifierSingleValue( statement, qualifier ) else itemId = statement.mainsnak.datavalue.value end
if itemId and project then itemId = mw.wikibase.getSitelink( itemId, project ) end
if not itemId then return nil end
local qualifiers = getQualifierValues( statement ) local languages = qualifiers[ 'P407' ] if not languages then languages = {} end
local refs = {} if qualifiers[ 'P400' ] then for _, refQid in ipairs( qualifiers[ 'P400' ] ) do local refLabel = refLabels if refLabels[ refQid ] then refLabel = refLabels[ refQid ] else refLabel = mw.wikibase.label( refQid ) or refQid end if refLabel ~= refQid then if #qualifiers[ 'P400' ] > 3 then refLabel = refLabel .. ' + ' .. ( #qualifiers[ 'P400' ] - 1 ) .. ' платформ' table.insert( refs, refLabel ) break end
table.insert( refs, refLabel ) end end end
return { itemId = itemId, qualifiers = qualifiers, languages = languages, refs = refs, rank = rank, } end
local function collectLinks( configuration, entityId, separateLabel ) -- Create rows local elements = {} local data = {}
for _, params in pairs( configuration ) do local resourceId = params local propertyId = resourceId[ 2 ] local qid if string.match( propertyId, '^P%d+:Q%d+$' ) then local parts = mw.text.split( propertyId, ':', true ) propertyId = parts[ 1 ] qid = parts[ 2 ] end
local claims = mw.wikibase.getBestStatements( entityId, propertyId ) or {} for _, statement in pairs( claims ) do local linkData if not qid then linkData = getLinkData( statement ) elseif getValueFromSnak( statement.mainsnak ) == qid then for qualifierId, qualifierType in pairs( propertyQualifiers[ propertyId ] ) do local project = nil if qualifierType == 'iw' then project = params.project end linkData = getLinkData( statement, qualifierId, project ) if linkData then break end end end
if linkData then if not data[ resourceId ] then data[ resourceId ] = {} end table.insert( data[ resourceId ], linkData ) end end end
for resourceId, resourceDatas in pairs( data ) do data[ resourceId ] = filterByRank( resourceDatas ) end
for _, params in pairs( configuration ) do local resourceId = params local resourceDatas = data[ resourceId ] if resourceDatas ~= nil then local links = {} for _, resourceData in pairs( resourceDatas ) do if separateLabel then -- Label: ID1, ID2 table.insert( links, renderLinkWithRef( resourceData, , params[ 3 ], true ) ) else -- Label · Label local label = params[ 1 ] table.insert( elements, renderLinkWithRef( resourceData, label, params[ 3 ] ) ) end end if separateLabel and #links then local result = renderLabel( params[ 1 ] ) .. ': ' .. table.concat( links, ', ' ) table.insert( elements, result ) end end end
return elements end
function p.render( frame )
local colorArg =
local byTemplate
local entityId = nil
if frame ~= nil then
local parentArgs = frame:getParent().args
colorArg = parentArgs[ templateColorName ] or parentArgs[ 'color' ] or parentArgs[ 1 ] or
if parentArgs[ 'from' ] and parentArgs[ 'from' ] ~= then
entityId = string.upper( parentArgs[ 'from' ] )
elseif parentArgs[ 'd' ] and parentArgs[ 'd' ] ~= then
entityId = string.upper( parentArgs[ 'd' ] )
else
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
if colorArg ~= then
local firstChar = mw.ustring.sub( colorArg, 1, 1 )
if firstChar ~= '#' then
byTemplate = colorByTitle( frame, colorArg )
if byTemplate then
colorArg = byTemplate
end
end
end
end
if not entityId then return end
local navboxData = { name = 'External links', title = templateTitle, titlestyle = 'display:none', state = 'plain', bodyclass = 'hlist', bodystyle = 'padding-top:1px', } if colorArg and colorArg ~= then navboxData.groupstyle = 'background: ' .. colorArg .. ';' end
local rowIndex = 1
for _, groupData in pairs( data ) do local isAuthorityControl = groupData.isAuthorityControl local groupLabel = groupData.label local groupList = groupData.list local groupElements = collectLinks( groupList, entityId, isAuthorityControl ) if #groupElements > 0 then navboxData[ 'group' .. rowIndex ] = groupLabel navboxData[ 'list' .. rowIndex ] = renderList( groupElements )
if isAuthorityControl then if #groupElements > 5 then navboxData[ 'group' .. rowIndex ] = nil local templateStyles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Šablon:Navigacionnii tablic таблица/styles.css' } } local collapsibleNavbox = moduleNavbox._navbox( { title = groupLabel, list1 = navboxData['list' .. rowIndex], border = 'subgroup', navbar = 'plain', state = 'collapsed', titleclass = 'ts-navbox-plaintitle', bodyclass = 'authoritycontrol', titlestyle = navboxData.groupstyle, bodystyle = 'text-align: left;', } ) navboxData[ 'list' .. rowIndex ] = templateStyles .. collapsibleNavbox end end
rowIndex = rowIndex + 1 end end
if rowIndex == 1 then if mw.title.getCurrentTitle().namespace == 0 then return end return end
local buttons = frame:expandTemplate{ title = 'tnavbar-view', args = { templateLink } } ..
'
'
if navboxData[ 'group1' ] then
navboxData[ 'group1' ] = '
'
else
navboxData[ 'group1' ] = '
'
end
local out = moduleNavbox._navbox( navboxData )
if colorArg and colorArg ~= and not byTemplate then out = out .. end
return out end
return p