Module:Authority control: Difference between revisions

From Porn Base Central
Jump to navigation Jump to search
(Created page with "require('Module:No globals') local p = {} local title = mw.title.getCurrentTitle() local namespace = title.namespace local testcases = (string.sub(title.subpageText,1,9) == '...")
 
No edit summary
 
Line 1: Line 1:
require('Module:No globals')
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 p = {}
local linksPrefix = ''
local title = mw.title.getCurrentTitle()
local project = 'PBC'
local categoryTemplateEmpty = project .. ':The "Authority control" template is empty'
local namespace = title.namespace
local templateLink = 'Authority control'
local testcases = (string.sub(title.subpageText,1,9) == 'testcases')


local group1Label = 'Social networks'
--[[==========================================================================]]
local group2Label = 'Texts of works'
--[[ Category functions ]]
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
function p.getCatForId( id )
local catName = ''
local preferredLanguage = 'Q96'; -- english

if namespace == 0 then
local templateColorName = 'color';
catName = 'PBC articles with '..id..' identifiers'
-- Some projects have "named" colors, defined by templates
elseif namespace == 2 and not title.isSubpage then
function colorByTitle( frame, colorTitle )
catName = 'User pages with '..id..' identifiers'
local templateName = 'Color/' .. colorTitle;
else
local templateTitle = mw.title.makeTitle( 'Template', templateName );
catName = 'Miscellaneous pages with '..id..' identifiers'
if ( templateTitle == nil or not templateTitle.exists ) then
return false;
end
end
return frame:expandTemplate{ title = templateName };
return '[[Category:'..catName..']]'..p.redCatLink(catName)
end
end


-- Feel free to correct labels and categories, or add/remove sources here
function p.redCatLink( catName ) --catName == 'Blah' (not 'Category:Blah', not '[[Category:Blah]]')

if catName and catName ~= '' and
-- Non-localizable part (not need to localize )
testcases == false and
local moduleNavbox = require('Module:Navbox')
mw.title.new(catName, 14).exists == false
local moduleLanguages -- accessed if necessary
then

return '[[Category:Pages with red-linked authority control categories]]'
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
end

return ''
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
end


function getQualifierSingleValue( statement, qualifierName )
function p.createRow( id, label, rawValues, link, links, withUid, specialCat )
if (statement ~= nil
local catName = 'PBC articles with faulty '..(specialCat or id)..' identifiers'
and statement.qualifiers ~= nil
if links then -- all links[] use withUid = false; no check needed
and statement.qualifiers[qualifierName] ~= nil) then
local row = '*<span class="nowrap">'..label

for i, l in ipairs( links ) do
for qualifierIndex, qualifier in pairs( statement.qualifiers[qualifierName] ) do
if i == 1 then row = row..' '
if (qualifier.datavalue ~= nil
else row = row..', ' end
and qualifier.datavalue.type ~= nil
if l then
and qualifier.datavalue.value ~= nil) then
row = row..'<span class="uid">'..l..'</span>'

else
if ( qualifier.datavalue.type == "monolingualtext" ) then
row = row..'<span class="error">The '..id..' id '..rawValues[i]..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName)
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
end

return row..'</span>\n'
elseif link then
if withUid then
return '*<span class="nowrap">'..label..' <span class="uid">'..link..'</span></span>\n'
end
return '*<span class="nowrap">'..label..' '..link..'</span>\n'
end
end
return nil;
return '* <span class="error">The '..id..' id '..rawValues..' is not valid.</span>[[Category:'..catName..']]'..p.redCatLink(catName)..'\n'
end
end


function getQualifierValues( statement, qualifierName )
--[[=========================== Helper functions =============================]]
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
function p.append(str, c, length)
result[ #result + 1 ] = qualifier.datavalue.value;
while str:len() < length do
elseif ( qualifier.datavalue.type == "wikibase-entityid" ) then
str = c .. str
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
end
return str
return result;
end
end


function collectLinks( configuration, elementId )
--Returns the ISNI check digit isni must be a string where the 15 first elements are digits, e.g. 0000000066534145
--Create rows
function p.getIsniCheckDigit( isni )
local total = 0
local elements = {}
for i = 1, 15 do
local data = {}

local digit = isni:byte( i ) - 48 --Get integer value

total = (total + digit) * 2
local item = mw.wikibase.getEntity( elementId )
if item == nil or item.claims == nil then
return elements
end
end

local remainder = total % 11
if ( item.claims['P602'] ~= nil ) then
local result = (12 - remainder) % 11
local claim = item.claims['P602']
if result == 10 then
for _, statement in pairs( claim ) do
return "X"
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
end
return tostring( result )
end


for _, params in pairs( configuration ) do
--[[==========================================================================]]
local resourceId = params[2]
--[[ PornBaseData & documentation functions ]]
--[[==========================================================================]]


local claim = item.claims[ resourceId ]
function p.getIdsFromPornBaseData( itemId, property )
if ( claim ) then
local ids = {}
for _, statement in pairs( claim ) do
local statements = mw.wikibase.getBestStatements( itemId, property )
local rank = statement.rank or 'normal';
if statements then
if ( rank ~= 'deprecated' and statement.mainsnak.datavalue) then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
local itemId = statement.mainsnak.datavalue.value;
local languages = getQualifierValues( statement, 'P44' );
table.insert( ids, statement.mainsnak.datavalue.value )
if (data[resourceId] == nil) then
data[resourceId] = {};
end
table.insert( data[resourceId], { itemId = itemId, languages = languages, rank = rank} );
end
end
end
end
end
end
end
return ids
end


for resourceId, resourceDatas in pairs( data ) do
function p.matchesPornBaseDataRequirements( itemId, reqs )
data[resourceId] = filterByRank( resourceDatas );
for _, group in ipairs( reqs ) do
end
local property = 'P'..group[1]
local qid = group[2]
local statements = mw.wikibase.getBestStatements( itemId, property )
if statements then
for _, statement in ipairs( statements ) do
if statement.mainsnak.datavalue then
if statement.mainsnak.datavalue.value['numeric-id'] == qid then
return true
end end end end end
return false
end


local hasNonOptionalLinks = false
-- Creates a human-readable standalone wikitable version of p.conf, and tracking categories with page counts, for use in the documentation

function p.docConfTable( frame )
for _, params in pairs( configuration ) do
local wikiTable = '{| class="wikitable sortable"\n'..
local resourceId = params[2]
'! rowspan=2 | Parameter\n'..
local optional = params[5] or false;
'! rowspan=2 | Label\n'..

'! rowspan=2; data-sort-type=number | PornBaseData property\n'..
local resourceDatas = data[resourceId];
'! colspan=4 | Tracking categories and page counts\n'..
if resourceDatas ~= nil then
'|-\n'..
if ( not optional ) then
'! [[:Category:PBC articles with authority control information|'.. 'Articles]]\n'..
hasNonOptionalLinks = true
'! [[:Category:User pages with authority control information|'.. 'User pages]]\n'..
end
'! [[:Category:Miscellaneous pages with authority control information|'.. 'Misc. pages]]\n'..

'! [[:Category:PBC articles with faulty authority control information|'..'Faulty IDs]]\n'..
local resourceLabel = renderLabel( params[1] );
'|-\n'
local firstChar = mw.ustring.sub( resourceLabel, 1, 1 );
local separateDesign = firstChar == '[' or firstChar == '<';
local lang = mw.getContentLanguage()

for _, conf in pairs( p.conf ) do
local param, link, pid = conf[1], conf[2], conf[3]
local html = '';
if ( separateDesign ) then
local category = conf.category or param
html = html .. resourceLabel .. ':&nbsp;';
local args = { id = 'f', pid }
end
local wpl = frame:expandTemplate{ title = 'PBD property link', args = args }

--cats
local preitemId
local articleCat = 'PBC articles with '..category..' identifiers'
for index, resourceData in pairs(resourceDatas) do
local userCat = 'User pages with '..category..' identifiers'
local itemId = resourceData.itemId;
local miscCat = 'Miscellaneous pages with '..category..' identifiers'
if index == 2 then
local faultyCat = 'PBC articles with faulty '..category..' identifiers'
--даёт возможность поставить id из одного свойства в разные ссылки
--counts
if itemId == preitemId then
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
break
local userCount = lang:formatNum( mw.site.stats.pagesInCategory(userCat, 'pages') )
end
local miscCount = lang:formatNum( mw.site.stats.pagesInCategory(miscCat, 'pages') )
end
local faultyCount = lang:formatNum( mw.site.stats.pagesInCategory(faultyCat, 'pages') )

--concat
local languages = resourceData.languages;
wikiTable = wikiTable..'\n'..
'|-\n'..
local link;
if type( params[3] ) == 'string' then
'||'..param..
link = replace( params[3], '$1', itemId );
'||'..link..
else
'||data-sort-value='..pid..'|'..wpl..
link = params[3] ( itemId );
'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..
end
'||style="text-align: right;"|[[:Category:'.. userCat..'|'.. userCount..']]'..
local linkFirstChar;
'||style="text-align: right;"|[[:Category:'.. miscCat..'|'.. miscCount..']]'..
local interwiki;
'||style="text-align: right;"|[[:Category:'.. faultyCat..'|'.. faultyCount..']]'
if ( link ) then
linkFirstChar = mw.ustring.sub( link, 1, 1 );
interwiki = linkFirstChar == ':'
end
if ( separateDesign ) then
if ( index ~= 1 ) then
html = html .. ',&nbsp;'
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 .. ':&nbsp;' .. 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 .. '&nbsp;' .. 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
end

if ( not hasNonOptionalLinks ) then
--append derivative WorldCat cats
return {}
local wcd = { 'WorldCat-LCCN', 'WorldCat-VIAF' }
for _, w in pairs(wcd) do
local articleCat = 'PBC articles with '..w..' identifiers'
local articleCount = lang:formatNum( mw.site.stats.pagesInCategory(articleCat, 'pages') )
wikiTable = wikiTable..'\n'..
'|-\n'..
'||'..'—'..
'||'..w..
'||data-sort-value='..w..'|'..'—'..
'||style="text-align: right;"|[[:Category:'..articleCat..'|'..articleCount..']]'..
'||style="text-align: right;"|—'..
'||style="text-align: right;"|—'..
'||style="text-align: right;"|—'
end
end

return wikiTable..'\n|}'
return elements
end
end


function collectDictionaryLinks( elementId )
--[[==========================================================================]]
--Create rows
--[[ Configuration ]]
local elements = {}
--[[==========================================================================]]


local item = mw.wikibase.getEntity( elementId );
-- If a specific "(identifier) redirect" exists for an identifier, please route through this particular redirect rather than linking directly to the target page. This reduces clutter in "What links here" and improves reverse lookup of articles where a manifestation of this particular identifier is used.
if ( item == nil or item.claims == nil) then
return elements
end


local sourceToElementLinks = {};
-- Check that the PornBaseData item has this property-->value before adding it
local reqs = {}


local claim = item.claims['P68']
--[[==========================================================================]]
if ( claim ) then
--[[ Main ]]
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 ?
function p.authorityControl( frame )
local entityId = getQualifierSingleValue( statement, 'P250' ) or getQualifierSingleValue( statement, 'P15' );
local resolveEntity = require( "Module:ResolveEntityId" )
if ( entityId ) then
local parentArgs = frame:getParent().args
if (sourceToElementLinks[resourceId] == nil) then
local elements = {} --create/insert rows later
sourceToElementLinks[resourceId] = {};
local worldcatCat = ''
end
local multipleIdCat = ''
table.insert( sourceToElementLinks[resourceId], { entityId = entityId, languages = languages, rank = rank } );
local suppressedIdCat = ''
end
local deprecatedIdCat = ''

-- URL to encyclopedia
--Redirect aliases to proper parameter names
local url = getQualifierSingleValue( statement, 'P324' );
for _, a in pairs( p.aliases ) do
local alias, param = a[1], a[2]
if (url == nil) then
-- no longer recommend, but widely used
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[alias] then
url = getQualifierSingleValue( statement, 'P35' );
parentArgs[param] = parentArgs[alias]
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
end
end

for _, description in pairs( data.dictionaries ) do
--Redirect deprecated parameters to proper parameter names, and assign tracking cat
if ( description.linkF ) then
for _, d in pairs( p.deprecated ) do
local dep, param = d[1], d[2]
local claim = item.claims[ description.id ];
if ( claim ) then
if (parentArgs[param] == nil or parentArgs[param] == '') and parentArgs[dep] then
for _, statement in pairs( claim ) do
parentArgs[param] = parentArgs[dep]
local rank = statement.rank or 'normal';
if namespace == 0 then
if ( rank ~= 'deprecated' and statement.mainsnak.datavalue) then
deprecatedIdCat = '[[Category:PBC articles with deprecated authority control identifiers|'..dep..']]'
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
end
end
end

local html = '';
--Use QID= parameter for testing/example purposes only
for _, description in pairs( data.dictionaries ) do
local itemId = nil
local links = sourceToElementLinks[ description.id ];
if namespace ~= 0 then
if ( links ) then
local qid = parentArgs['qid'] or parentArgs['QID']
for _, link in pairs( links ) do
if qid then
if ( link.url ) then
itemId = 'Q'..mw.ustring.gsub(qid, '^[Qq]', '')
table.insert( elements, '[' .. link.url .. ' ' .. description.title .. ']' );
itemId = resolveEntity._id(itemId) --nil if unresolvable
end
end

else
if ( link.entityId ) then
itemId = mw.wikibase.getEntityIdForCurrentPage()
local sitelink = mw.wikibase.getSitelink( link.entityId, description.project );
end
if ( sitelink ) then
table.insert( elements, '[[' .. description.projectCode .. sitelink .. '|' .. description.title .. ']]' );
--PornBaseData fallback if requested
if itemId then
for _, params in ipairs( p.conf ) do
if params[3] > 0 then
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
if val == nil or val == '' then
local canUsePornBaseData = nil
if reqs[params[1]] then
canUsePornBaseData = p.matchesPornBaseDataRequirements( itemId, reqs[params[1]] )
else
canUsePornBaseData = true
end
end
if canUsePornBaseData then
local wikidataIds = p.getIdsFromPornBaseData( itemId, 'P'..params[3] )
if wikidataIds[1] then
if val == '' and (namespace == 0 or testcases) then
suppressedIdCat = '[[Category:PBC articles with suppressed authority control identifiers|'..params[1]..']]'
else
parentArgs[params[1]] = wikidataIds[1]
end end end end end end end
--Configured rows
local rct = 0
for _, params in ipairs( p.conf ) do
local val = parentArgs[mw.ustring.lower(params[1])] or parentArgs[params[1]]
local tval, tlinks = {}, {}
if val and val ~= '' and type(params[4]) == 'function' then
table.insert( tval, val )
table.insert( tlinks, params[4]( val ) )
end
-- collect other unique vals (IDs) from WD, if present
if itemId and tval[1] then
local wikidataIds = p.getIdsFromPornBaseData( itemId, 'P'..params[3] )
for _, v in pairs( wikidataIds ) do
local bnew = true
for _, w in pairs( tval ) do
if v == w then bnew = false end
end
if bnew then
table.insert( tval, v )
table.insert( tlinks, params[4]( v ) )
end
end
end
end
end
end
end
-- assemble

if tval[1] then
return elements
table.insert( elements, p.createRow( params[1], params[2]..':', tval, nil, tlinks, true, params.category ) )
end
rct = rct + 1

if tval[2] then
function contains( tableStructure, value )
multipleIdCat = p.getCatForId( 'multiple' )
if ( tableStructure == nil or value == nil) then
end
return true;
end
for index, line in pairs( tableStructure ) do
if ( line == value ) then
return true;
end
end
end
end
return false;
end
--WorldCat

local worldcatId = parentArgs['worldcatid'] or parentArgs['WORLDCATID']
function filterByRank( resourceDatas )
if worldcatId and worldcatId ~= '' then --if WORLDCATID present & unsuppressed
-- itemId, languages. rank = rank
table.insert( elements, p.createRow( 'WORLDCATID', '', worldcatId, '[[WorldCat Identities (identifier)|WorldCat Identities]]: [https://www.worldcat.org/identities/'..mw.uri.encode(worldcatId, 'PATH')..' '..worldcatId..']', nil, false ) ) --Validation?

worldcatCat = p.getCatForId( 'WORLDCATID' )
local hasPreffered = false;
elseif worldcatId == nil then --if WORLDCATID absent but unsuppressed
for index, resourceData in pairs(resourceDatas) do
local viafId = parentArgs['viaf'] or parentArgs['VIAF']
if ( resourceData.rank == 'preferred' ) then
local lccnId = parentArgs['lccn'] or parentArgs['LCCN']
hasPreffered = true;
if viafId and viafId ~= '' and p.viafLink( viafId ) then --VIAF must be present, unsuppressed, & validated
end
table.insert( elements, p.createRow( 'VIAF', '', viafId, '[[WorldCat Identities (identifier)|WorldCat Identities]] (via VIAF): [https://www.worldcat.org/identities/containsVIAFID/'..viafId..' '..viafId..']', nil, false ) )
end
if namespace == 0 then

worldcatCat = '[[Category:PBC articles with WorldCat-VIAF identifiers]]'
if (not hasPreffered) then
end
return resourceDatas;
elseif lccnId and lccnId ~= '' and p.lccnLink( lccnId ) then --LCCN must be present, unsuppressed, & validated
end
local lccnParts = p.splitLccn( lccnId )

if lccnParts and lccnParts[1] ~= 'sh' then
local result = {};
local lccnIdFmtd = lccnParts[1]..lccnParts[2]..'-'..lccnParts[3]
for index, resourceData in pairs(resourceDatas) do
table.insert( elements, p.createRow( 'LCCN', '', lccnId, '[[WorldCat Identities (identifier)|WorldCat Identities]] (via LCCN): [https://www.worldcat.org/identities/lccn-'..lccnIdFmtd..' '..lccnIdFmtd..']', nil, false ) )
if ( resourceData.rank == 'preferred' or contains(resourceData.languages, preferredLanguage) ) then
if namespace == 0 then
table.insert(result, resourceData);
worldcatCat = '[[Category:PBC articles with WorldCat-LCCN identifiers]]'
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
end
end
elseif worldcatId == '' then --if WORLDCATID suppressed
suppressedIdCat = '[[Category:PBC articles with suppressed authority control identifiers|WORLDCATID]]'
end
end

local Navbox = require('Module:Navbox')
local navboxData = {
name = 'Authority control',
local elementsCat = ''
navboxclass = 'navbox pbcArticleExternalLinksTable',
if rct == 0 or rct >= 25 then
bodyclass = 'hlist',
local eCat = 'AC with '..rct..' elements'
};
elementsCat = '[[Category:'..eCat..']]'..p.redCatLink(eCat)
if colorArg and colorArg ~= '' then
navboxData.groupstyle = 'background: ' .. colorArg .. ';';
end
end

local outString = ''
local rowIndex = 1;

if #elements > 0 then
local socialNetworksElements = collectLinks( data.socialNetworkProperties, elementId );
local args = { pid = 'identifiers' } -- #target the list of identifiers
if ( #socialNetworksElements > 0 ) then
if testcases and itemId then args = { pid = 'identifiers', qid = itemId } end --expensive
navboxData['group' .. rowIndex] = group1Label;
local pencil = frame:expandTemplate{ title = 'EditAtPornBaseData', args = args}
navboxData['list' .. rowIndex] = table.concat( socialNetworksElements , ' · ' );
outString = Navbox._navbox( {
rowIndex = rowIndex + 1;
name = 'Authority control',
navboxclass = 'authority-control',
bodyclass = 'hlist',
group1 = '[[Help:Authority control|Authority control]]'..pencil,
list1 = table.concat( elements )
} )
end
end

local textsElements = collectLinks( data.textsProperties, elementId );
local auxCats = worldcatCat .. elementsCat .. multipleIdCat .. suppressedIdCat .. deprecatedIdCat
if testcases then
if ( #textsElements > 0 ) then
navboxData['group' .. rowIndex] = group2Label;
auxCats = mw.ustring.gsub(auxCats, '(%[%[)(Category)', '%1:%2') --for easier checking
navboxData['list' .. rowIndex] = table.concat( textsElements , ' · ' );
rowIndex = rowIndex + 1;
end
end

outString = outString .. auxCats
local contentHostingElements = collectLinks( data.contentHostingProperties, elementId );
if namespace ~= 0 then
if ( #contentHostingElements > 0 ) then
outString = mw.ustring.gsub(outString, '(%[%[)(Category:PBC articles)', '%1:%2') --by definition
navboxData['group' .. rowIndex] = group3Label;
navboxData['list' .. rowIndex] = table.concat( contentHostingElements , ' · ' );
rowIndex = rowIndex + 1;
end
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>&nbsp;&nbsp;' ..
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';
return outString
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 .. '| &nbsp; \n';
end

if ( category ~= nil and category ~= false ) then
result = result .. '| [[:Category:' .. category .. '|' .. category .. ']]\n';
else
result = result .. '| &nbsp; \n';
end
result = result .. '| ' .. optional .. '\n';
result = result .. '|-\n';
end

return result;
end
end



Latest revision as of 05:05, 28 February 2021

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 .. ':&nbsp;';
			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 .. ',&nbsp;'
					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 .. ':&nbsp;' .. 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 .. '&nbsp;' .. 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>&nbsp;&nbsp;' ..
				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 .. '| &nbsp; \n';
		end

		if ( category ~= nil and category ~= false ) then
			result = result .. '| [[:Category:' .. category .. '|' .. category .. ']]\n';
		else
			result = result .. '| &nbsp; \n';
		end
		result = result .. '| ' .. optional .. '\n';
		result = result .. '|-\n';
	end

	return result;
end

return p