Module:Authority control
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Authority control/doc
local data = require('Module:Authority control/data') -- Localizable part -- Please, note, that labels to various sites and cataloges are taken from Wikidata (i.e. Wikidata label) local linksPrefix = '' local project = 'PBC' local categoryTemplateEmpty = project .. ':The "Authority control" template is empty' local templateLink = 'Authority control' local group1Label = 'Social networks' local group2Label = 'Texts of works' local group3Label = 'Photo, video and audio' local group4Label = 'Thematic sites' local group5Label = 'Dictionaries and encyclopedias' local group6Label = 'Genealogy and necropolis' local group7Label = 'Taxonomy' local group8Label = 'Authority control' -- The language codes that should be always displayed even if they have normal rank and claim with another language and prefferered rank exists local preferredLanguage = 'Q96'; -- english local templateColorName = 'color'; -- Some projects have "named" colors, defined by templates function colorByTitle( frame, colorTitle ) local templateName = 'Color/' .. colorTitle; local templateTitle = mw.title.makeTitle( 'Template', templateName ); if ( templateTitle == nil or not templateTitle.exists ) then return false; end return frame:expandTemplate{ title = templateName }; end -- Feel free to correct labels and categories, or add/remove sources here -- Non-localizable part (not need to localize ) local moduleNavbox = require('Module:Navbox') local moduleLanguages -- accessed if necessary local titleBasedLinks = { ['Q602358'] = true, ['Q17290934'] = true, ['Q1960551'] = true } local p = {} function link( url ) return url end function replace( str, pattern, repl ) pattern = mw.ustring.gsub( pattern, "[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1" ); -- escape pattern repl = mw.ustring.gsub( repl, "[%%]", "%%%%" ); -- escape replacement return mw.ustring.gsub( str, pattern, repl ); end function renderLabel( params ) if type( params ) == 'string' then return params; end local id = params[ 1 ]; local default = params[ 2 ]; if #params >= 3 then local label = params[ 3 ]; local link = mw.wikibase.sitelink( id ); if ( link ~= nil ) then return '[[' .. link .. '|' .. label .. ']]'; end local title = mw.wikibase.label( id ) or default; return '<span title="' .. title .. '" style="border-bottom: 1px dotted; cursor: help;">' .. label .. '</span>' end return mw.wikibase.label( id ) or default; end function getQualifierSingleValue( statement, qualifierName ) if (statement ~= nil and statement.qualifiers ~= nil and statement.qualifiers[qualifierName] ~= nil) then for qualifierIndex, qualifier in pairs( statement.qualifiers[qualifierName] ) do if (qualifier.datavalue ~= nil and qualifier.datavalue.type ~= nil and qualifier.datavalue.value ~= nil) then if ( qualifier.datavalue.type == "monolingualtext" ) then return qualifier.datavalue.value.text; end if ( qualifier.datavalue.type == "string" ) then return qualifier.datavalue.value; end if ( qualifier.datavalue.type == "wikibase-entityid" ) then return qualifier.datavalue.value.id; end mw.log( 'Unknown qualifier type: ' .. qualifier.datavalue.type ) return qualifier.datavalue.value; end end end return nil; end function getQualifierValues( statement, qualifierName ) local result = {} if (statement ~= nil and statement.qualifiers ~= nil and statement.qualifiers[qualifierName] ~= nil) then local qualifiers = statement.qualifiers[qualifierName]; for _, qualifier in pairs( qualifiers ) do if (qualifier.datavalue ~= nil and qualifier.datavalue.type ~= nil and qualifier.datavalue.value ~= nil) then if ( qualifier.datavalue.type == "string" ) then result[ #result + 1 ] = qualifier.datavalue.value; elseif ( qualifier.datavalue.type == "wikibase-entityid" ) then result[ #result + 1 ] = qualifier.datavalue.value.id; else mw.log( 'Unknown qualifier type: ' .. qualifier.datavalue.type ); result[ #result + 1 ] = qualifier.datavalue.value; end end end end return result; end function collectLinks( configuration, elementId ) --Create rows local elements = {} local data = {} local item = mw.wikibase.getEntity( elementId ) if item == nil or item.claims == nil then return elements end if ( item.claims['P602'] ~= nil ) then local claim = item.claims['P602'] for _, statement in pairs( claim ) do if (statement ~= nil) then -- profile ID local rank = statement.rank or 'normal'; if ( rank ~= 'deprecated' ) then local itemId = getQualifierSingleValue( statement, 'P603' ); if (itemId ~= nil) then -- language local languages = getQualifierValues( statement, 'P44' ); local resourceId = statement.mainsnak.datavalue.value.id; if (data[resourceId] == nil) then data[resourceId] = {}; end table.insert( data[resourceId], { itemId = itemId, languages = languages, rank = rank} ); end end end end end for _, params in pairs( configuration ) do local resourceId = params[2] local claim = item.claims[ resourceId ] if ( claim ) then for _, statement in pairs( claim ) do local rank = statement.rank or 'normal'; if ( rank ~= 'deprecated' and statement.mainsnak.datavalue) then local itemId = statement.mainsnak.datavalue.value; local languages = getQualifierValues( statement, 'P44' ); if (data[resourceId] == nil) then data[resourceId] = {}; end table.insert( data[resourceId], { itemId = itemId, languages = languages, rank = rank} ); end end end end for resourceId, resourceDatas in pairs( data ) do data[resourceId] = filterByRank( resourceDatas ); end local hasNonOptionalLinks = false for _, params in pairs( configuration ) do local resourceId = params[2] local optional = params[5] or false; local resourceDatas = data[resourceId]; if resourceDatas ~= nil then if ( not optional ) then hasNonOptionalLinks = true end local resourceLabel = renderLabel( params[1] ); local firstChar = mw.ustring.sub( resourceLabel, 1, 1 ); local separateDesign = firstChar == '[' or firstChar == '<'; local html = ''; if ( separateDesign ) then html = html .. resourceLabel .. ': '; end local preitemId for index, resourceData in pairs(resourceDatas) do local itemId = resourceData.itemId; if index == 2 then --даёт возможность поставить id из одного свойства в разные ссылки if itemId == preitemId then break end end local languages = resourceData.languages; local link; if type( params[3] ) == 'string' then link = replace( params[3], '$1', itemId ); else link = params[3] ( itemId ); end local linkFirstChar; local interwiki; if ( link ) then linkFirstChar = mw.ustring.sub( link, 1, 1 ); interwiki = linkFirstChar == ':' end if ( separateDesign ) then if ( index ~= 1 ) then html = html .. ', ' end if ( link ) then if ( interwiki ) then html = html .. '[[' .. link .. '|' .. itemId .. ']]'; else html = html .. '[' .. link .. ' ' .. itemId .. ']'; end else html = html .. itemId; end else if ( index ~= 1 ) then html = html .. ' · ' end if ( link ) then if ( interwiki ) then html = html .. '[[' .. link .. '|' .. resourceLabel .. ']]'; else html = html .. '[' .. link .. ' ' .. resourceLabel .. ']'; end else -- it should not happen html = html .. resourceLabel .. ': ' .. itemId; end if ( languages ~= nil 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', 'PornBaseData/Language-codes' ).exists) then moduleLanguages = require('Module:Languages'); else moduleLanguages = false; end end if ( moduleLanguages ) then for langIndex, language in pairs(languages) do html = html .. ' ' .. moduleLanguages.getRefHtml( language ) end end end end preitemId = resourceData.itemId; end if ( #params >= 4 and params[4] ) then html = html .. '[[Category:' .. params[4] .. ']]' end table.insert( elements, html ) end end if ( not hasNonOptionalLinks ) then return {} end return elements end function collectDictionaryLinks( elementId ) --Create rows local elements = {} local item = mw.wikibase.getEntity( elementId ); if ( item == nil or item.claims == nil) then return elements end local sourceToElementLinks = {}; local claim = item.claims['P68'] if ( claim ) then for _, statement in pairs( claim ) do if (statement ~= nil) then local rank = statement.rank or 'normal'; if ( rank ~= 'deprecated' ) then local resourceId = statement.mainsnak.datavalue.value.id; local languages = getQualifierValues( statement, 'P44' ); -- Wikisource link ? local entityId = getQualifierSingleValue( statement, 'P250' ) or getQualifierSingleValue( statement, 'P15' ); if ( entityId ) then if (sourceToElementLinks[resourceId] == nil) then sourceToElementLinks[resourceId] = {}; end table.insert( sourceToElementLinks[resourceId], { entityId = entityId, languages = languages, rank = rank } ); end -- URL to encyclopedia local url = getQualifierSingleValue( statement, 'P324' ); if (url == nil) then -- no longer recommend, but widely used url = getQualifierSingleValue( statement, 'P35' ); end if ( url ~= nil ) then if (sourceToElementLinks[resourceId] == nil) then sourceToElementLinks[resourceId] = {}; end table.insert( sourceToElementLinks[resourceId], { url = url, languages = languages, rank = rank } ); end end end end end for _, description in pairs( data.dictionaries ) do if ( description.linkF ) then local claim = item.claims[ description.id ]; if ( claim ) then for _, statement in pairs( claim ) do local rank = statement.rank or 'normal'; if ( rank ~= 'deprecated' and statement.mainsnak.datavalue) then local value = statement.mainsnak.datavalue.value; local url; if type( description.linkF ) == 'string' then url = replace( description.linkF, '$1', value ); else url = description.linkF( value ); end local languages = getQualifierValues( statement, 'P44' ); if ( sourceToElementLinks[description.id] == nil) then sourceToElementLinks[description.id] = {}; end table.insert( sourceToElementLinks[description.id], { url = url, languages = languages, rank = rank} ); end end end end end local html = ''; for _, description in pairs( data.dictionaries ) do local links = sourceToElementLinks[ description.id ]; if ( links ) then for _, link in pairs( links ) do if ( link.url ) then table.insert( elements, '[' .. link.url .. ' ' .. description.title .. ']' ); end if ( link.entityId ) then local sitelink = mw.wikibase.getSitelink( link.entityId, description.project ); if ( sitelink ) then table.insert( elements, '[[' .. description.projectCode .. sitelink .. '|' .. description.title .. ']]' ); end end end end end return elements end function contains( tableStructure, value ) if ( tableStructure == nil or value == nil) then return true; end for index, line in pairs( tableStructure ) do if ( line == value ) then return true; end end return false; end 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 function p.render( frame ) local colorArg = ''; local elementId = 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 elementId = string.upper( parentArgs['from'] ); elseif parentArgs['d'] and parentArgs['d'] ~= '' then elementId = string.upper( parentArgs['d'] ); end if ( colorArg ~= '' ) then local firstChar = mw.ustring.sub( colorArg, 1, 1 ); if ( firstChar ~= '#' ) then local byTemplate = colorByTitle( frame, colorArg ); if ( byTemplate ) then colorArg = byTemplate; end end end end local navboxData = { name = 'Authority control', navboxclass = 'navbox pbcArticleExternalLinksTable', bodyclass = 'hlist', }; if colorArg and colorArg ~= '' then navboxData.groupstyle = 'background: ' .. colorArg .. ';'; end local rowIndex = 1; local socialNetworksElements = collectLinks( data.socialNetworkProperties, elementId ); if ( #socialNetworksElements > 0 ) then navboxData['group' .. rowIndex] = group1Label; navboxData['list' .. rowIndex] = table.concat( socialNetworksElements , ' · ' ); rowIndex = rowIndex + 1; end local textsElements = collectLinks( data.textsProperties, elementId ); if ( #textsElements > 0 ) then navboxData['group' .. rowIndex] = group2Label; navboxData['list' .. rowIndex] = table.concat( textsElements , ' · ' ); rowIndex = rowIndex + 1; end local contentHostingElements = collectLinks( data.contentHostingProperties, elementId ); if ( #contentHostingElements > 0 ) then navboxData['group' .. rowIndex] = group3Label; navboxData['list' .. rowIndex] = table.concat( contentHostingElements , ' · ' ); rowIndex = rowIndex + 1; end local themeProfilesElements = collectLinks( data.themeProfilesProperties, elementId ); if ( #themeProfilesElements > 0 ) then navboxData['group' .. rowIndex] = group4Label; navboxData['list' .. rowIndex] = table.concat( themeProfilesElements , ' · ' ); rowIndex = rowIndex + 1; end local dictionaryElements = collectDictionaryLinks( elementId ); if ( #dictionaryElements > 0 ) then navboxData['group' .. rowIndex] = group5Label; navboxData['list' .. rowIndex] = table.concat( dictionaryElements , ' · ' ); rowIndex = rowIndex + 1; end local geniElements = collectLinks( data.geniGraves, elementId ); if ( #geniElements > 0 ) then navboxData['group' .. rowIndex] = group6Label; navboxData['list' .. rowIndex] = table.concat( geniElements , ' · ' ); rowIndex = rowIndex + 1; end local taxElements = collectLinks( data.taxons, elementId ); if ( #taxElements > 0 ) then navboxData['group' .. rowIndex] = group7Label; navboxData['list' .. rowIndex] = table.concat( taxElements , ' · ' ); rowIndex = rowIndex + 1; end local authorityControlElements = collectLinks( data.authorityControl, elementId ); local authorityControlExtElements = collectLinks( data.authorityControlExt, elementId ); if ( #authorityControlElements > 0 ) then navboxData['group' .. rowIndex] = group8Label; if ( #authorityControlExtElements > 0 ) then navboxData['list' .. rowIndex] = table.concat( authorityControlElements , ' · ' ) .. ' · ' .. table.concat( authorityControlExtElements , ' · ' ); else navboxData['list' .. rowIndex] = table.concat( authorityControlElements , ' · ' ); end if ( #authorityControlElements > 5 ) then navboxData['group' .. rowIndex] = nil; package.loaded['Module:Navbox'] = nil; local templateStyles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Navbar-table/styles.css' } }; local collapsibleNavbox = require('Module:Navbox')._navbox( { title = group8Label, 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 rowIndex = rowIndex + 1; end if ( rowIndex == 1 ) then if ( mw.title.getCurrentTitle().namespace == 0 ) then return '[[Category:' .. categoryTemplateEmpty .. ']]'; end else if navboxData['group1'] then navboxData['group1'] = '<div style="padding: 0px 18px 0px 0px; width: 100%;"><div style="float: left;">' .. frame:expandTemplate{ title = 'tnavbar-view', args = { templateLink } } .. '</div> ' .. navboxData['group1'] .. '</div>'; else navboxData['group1'] = '<div style="padding: 0px 0px 0px 0px; width: 100%;">' .. frame:expandTemplate{ title = 'tnavbar-view', args = { templateLink } } .. '</div>'; end end local navbox = moduleNavbox._navbox( navboxData ) return navbox end function p.renderDocumentation() local result = '' result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group1Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.socialNetworkProperties ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group2Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.textsProperties ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group3Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.contentHostingProperties ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group4Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.themeProfilesProperties ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group5Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.dictionaries ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group6Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.geniGraves ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group7Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.taxons ); result = result .. '|-\n'; result = result .. '! colspan=4 | ' .. group8Label .. '\n'; result = result .. '|-\n'; result = result .. renderDocumentationCategory( data.authorityControl ); return result; end function renderDocumentationCategory( links ) local result = ''; for _, params in pairs( links ) do local resourceLabel = renderLabel( params[ 1 ] or params.title ); local resourceId = params[ 2 ] or params.id; local category = params[ 4 ]; local optional; if ( params[ 5 ] or false ) then optional = 'TRUE'; else optional = 'FALSE'; end result = result .. '| ' .. resourceLabel .. '\n'; if string.match( resourceId, '^P' ) then result = result .. '| [[:d:Property:' .. resourceId .. '|' .. resourceId .. ']]\n'; elseif string.match( resourceId, '^Q' ) then result = result .. '| [[:d:' .. resourceId .. '' .. '|' .. resourceId .. ']]\n'; else result = result .. '| \n'; end if ( category ~= nil and category ~= false ) then result = result .. '| [[:Category:' .. category .. '|' .. category .. ']]\n'; else result = result .. '| \n'; end result = result .. '| ' .. optional .. '\n'; result = result .. '|-\n'; end return result; end return p