Modul:Article: Unterschied zwischen den Versionen

IMT HilfeWiki - das Wiki
(16 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 3: Zeile 3:
 
local _CFG = mw.loadData('Modul:Article/config')
 
local _CFG = mw.loadData('Modul:Article/config')
 
local _TT = require('Module:TableTools')
 
local _TT = require('Module:TableTools')
local _SMWUTIL = require('Module:Smwutil')
+
local _SMWUTIL = require('Module:SmwUtil')
  
 
local article = {}
 
local article = {}
Zeile 11: Zeile 11:
 
function getPagesInCategory(category)
 
function getPagesInCategory(category)
 
if category and #category > 0 then
 
if category and #category > 0 then
return _SMWUTIL.luaask({'[[Category:' .. category .. ']]'}, {'?'}, nil, 'arr')
+
local result = _SMWUTIL.ask({select = '[[Category:' .. category .. ']]', fields = {}}, { mainlabel = 'pageName' } )
 +
local ret = {}
 +
for _, v in pairs(result) do
 +
if v.pageName and #v.pageName > 0 then
 +
ret[v.pageName] = v.pageName
 +
end
 +
end
 +
return ret
 
else
 
else
 
return nil
 
return nil
Zeile 19: Zeile 26:
 
function getOs2osfamily()
 
function getOs2osfamily()
 
if #os2osfamily == 0 then
 
if #os2osfamily == 0 then
local result = _SMWUTIL.luaask('[[Category:Betriebssysteme]]', 'is member of os family')
+
local result = _SMWUTIL.ask({ select = '[[Category:Betriebssysteme]]', fields = 'is member of os family#-=family' }, { mainlabel = 'pageName' })
 
if not result or _TT.size(result) == 0 then
 
if not result or _TT.size(result) == 0 then
 
os2osfamily = _CFG.os2osfamily
 
os2osfamily = _CFG.os2osfamily
 
else
 
else
for os, osdata in pairs(result) do
+
for _, osdata in pairs(result) do
os2osfamily[mw.ustring.lower(os)] = mw.ustring.lower(osdata['is member of os family'])
+
if osdata.pageName and osdata.family then
os2osfamily[os] = mw.ustring.lower(osdata['is member of os family'])
+
os2osfamily[mw.ustring.lower(osdata.pageName)] = mw.ustring.lower(osdata.family)
 +
os2osfamily[osdata.pageName] = mw.ustring.lower(osdata.family)
 +
end
 
end
 
end
 
end
 
end
Zeile 57: Zeile 66:
 
return ibType
 
return ibType
 
end
 
end
 +
end
 +
 +
function getPortalListFor( services )
 +
 +
local validTechnicalServices = {}
 +
for _, s in pairs( services ) do
 +
if not _CFG.fallBack2default[s] then
 +
table.insert( validTechnicalServices, s )
 +
end
 +
end
 +
 +
if #validTechnicalServices == 0 then
 +
return {}
 +
end
 +
 +
-- now build the query string and execute it
 +
local query = {
 +
select = '[[' .. table.concat( validTechnicalServices, ']] OR [[' ) .. ']]',
 +
fields = { 'Shows on service landing page#-=portal' }
 +
}
 +
local result = _SMWUTIL.ask( query, { mainlabel = 'service' } )
 +
 +
-- build the lookup
 +
local portalsLookup = {}
 +
for _, row in pairs( result ) do
 +
if type( row.portal ) ~= 'table' then
 +
row.portal = { row.portal }
 +
end
 +
portalsLookup[row.service] = row.portal
 +
portalsLookup[mw.ustring.lower(row.service)] = row.portal
 +
end
 +
 +
-- why use this loop instead of processing the query result directly?
 +
-- for the breadcrumb I want to prioritize services, so the parent
 +
-- is derived from the first entered service.
 +
-- Therefore I must base all my calculations on the original order
 +
-- of services instead of the query order
 +
 +
local alreadyProcessed = {}
 +
local portalList = {}
 +
for _, service in pairs( services ) do
 +
if portalsLookup[service] then
 +
for _, v in pairs( portalsLookup[service] ) do
 +
if not alreadyProcessed[v] then
 +
table.insert( portalList, v )
 +
alreadyProcessed[v] = true
 +
end
 +
end
 +
elseif _CFG.fallBack2default[service]
 +
and not alreadyProcessed[_CFG.control.displayDefaultAs]
 +
then
 +
table.insert( portalList, _CFG.control.displayDefaultAs )
 +
alreadyProcessed[_CFG.control.displayDefaultAs] = true
 +
end
 +
end
 +
 +
return portalList
 +
end
 +
 +
function printList( list, link, default )
 +
if not list or _TT.size( list ) == 0 then
 +
return default or ''
 +
end
 +
if not link then
 +
return mw.text.listToText( list, ', ', ' und ' )
 +
end
 +
local linkedList = {}
 +
local insertDefault = true
 +
for _, v in pairs( list ) do
 +
if not _CFG.fallBack2default[v] then
 +
table.insert( linkedList, '[[' .. v .. ']]' )
 +
elseif insertDefault then
 +
table.insert( linkedList, _CFG.control.displayDefaultAs )
 +
insertDefault = false
 +
end
 +
end
 +
return mw.text.listToText( linkedList, ', ', ' und ' )
 +
end
 +
 +
function split(str, sep)
 +
if type(str) == 'table' then
 +
return str
 +
end
 +
local r = {}
 +
if not sep then
 +
sep = ','
 +
end
 +
if str then
 +
for v in mw.text.gsplit(str, sep, true) do
 +
s = mw.text.trim(v)
 +
if mw.ustring.len(s) > 0 then
 +
table.insert(r, s)
 +
end
 +
end
 +
end
 +
if #r == 0 then
 +
r = nil
 +
end
 +
return r
 
end
 
end
  
Zeile 66: Zeile 174:
 
* checks all provided valid entries
 
* checks all provided valid entries
 
* sets default values for non mandatory and not provided parameters
 
* sets default values for non mandatory and not provided parameters
* adds a preceeding 'meta:' to service if omitted
+
* adds a preceeding 'Service:' to service if omitted
 
f
 
f
 
************** NOTE:
 
************** NOTE:
Zeile 83: Zeile 191:
 
local invalid = {}
 
local invalid = {}
 
if _CFG.validValues[arg] then
 
if _CFG.validValues[arg] then
for _, v in pairs(_SMWUTIL.split(args[arg])) do -- for every entry, check if it is valid
+
-- we only have valid values for type and targetgroup
 +
for _, v in pairs(split(args[arg])) do -- for every entry, check if it is valid
 
if _TT.inTable(_CFG.validValues[arg], v) then
 
if _TT.inTable(_CFG.validValues[arg], v) then
 
table.insert(valid, v)
 
table.insert(valid, v)
Zeile 91: Zeile 200:
 
end
 
end
 
else -- of if _CFG.validValues[arg] then
 
else -- of if _CFG.validValues[arg] then
valid = _SMWUTIL.split(args[arg])
+
-- os and service can be validated later, if requested
 +
valid = split(args[arg])
 
end -- of if _CFG.validValues[arg] then .. else
 
end -- of if _CFG.validValues[arg] then .. else
 
uservalues[arg] = valid
 
uservalues[arg] = valid
Zeile 111: Zeile 221:
 
end -- of for _, arg in pairs(_CFG.allParams) do
 
end -- of for _, arg in pairs(_CFG.allParams) do
  
-- special processing of service field. see to it, that all entries have a preceeding 'meta:'
+
-- special processing of service field. see to it, that all entries have a preceeding 'Service:'
 
for k, v in pairs(uservalues.service) do
 
for k, v in pairs(uservalues.service) do
if not mw.ustring.find(v, 'Meta:', 1, true) then
+
-- the following is for backwards compatibilty when we migrated services from ns meta to ns service
v = 'Meta:' .. v
+
if mw.ustring.find(v, 'Meta:', 1, true) then
uservalues.service[k] = v
+
-- this is due to legacy reasons. service entites were once stored in namespace meta
 +
uservalues.service[k] = mw.ustring.gsub(v, 'Meta', 'Service', 1)
 +
elseif not mw.ustring.find(v, 'Service:', 1, true) then
 +
uservalues.service[k] = 'Service:' .. v
 
end
 
end
 
end
 
end
Zeile 121: Zeile 234:
 
-- if requested, do some plausibility checks
 
-- if requested, do some plausibility checks
 
if _CFG.control.validateParamOs then
 
if _CFG.control.validateParamOs then
-- local valid_os = getPagesInCategory('Betriebssysteme')
+
-- valid_od is an associative list os -> osfamily. here, os is present as queried and in lowercase
 
local valid_os = getOs2osfamily()
 
local valid_os = getOs2osfamily()
 
local newvalues = {}
 
local newvalues = {}
Zeile 127: Zeile 240:
 
for _, os in pairs(uservalues.os) do
 
for _, os in pairs(uservalues.os) do
 
if not valid_os[mw.ustring.lower(os)] then
 
if not valid_os[mw.ustring.lower(os)] then
if _TT.inTable(_CFG.fallBack2default, os) then
+
-- this could happen, if user manually added one of the fallback defaults
 +
if _CFG.fallBack2default[os] then
 
if not fallingBack2default then
 
if not fallingBack2default then
 
table.insert(newvalues, _CFG.defaultValues.os[1])
 
table.insert(newvalues, _CFG.defaultValues.os[1])
Zeile 141: Zeile 255:
 
uservalues.os = newvalues
 
uservalues.os = newvalues
 
end -- of if _CFG.control.validateParamOs then
 
end -- of if _CFG.control.validateParamOs then
 +
 
if _CFG.control.validateParamService then
 
if _CFG.control.validateParamService then
 
local valid_service = getPagesInCategory('Services')
 
local valid_service = getPagesInCategory('Services')
 +
local inactive_service = getPagesInCategory('Inactive services')
 +
-- this is an associative list service -> service, whereas service is a pagename in ns service, e.g. Service:Mail
 +
local all_services = valid_service
 +
for k,v in pairs(inactive_service) do
 +
all_services[k] = v
 +
end
 
local newvalues = {}
 
local newvalues = {}
 
local fallingBack2default = nil
 
local fallingBack2default = nil
 
for _, service in pairs(uservalues.service) do
 
for _, service in pairs(uservalues.service) do
if not valid_service[service] then
+
if not all_services[service] then
if _TT.inTable(_CFG.fallBack2default, service) then
+
if _CFG.fallBack2default[service] then
 
if not fallingBack2default then
 
if not fallingBack2default then
 
table.insert(newvalues, _CFG.defaultValues.service[1])
 
table.insert(newvalues, _CFG.defaultValues.service[1])
Zeile 161: Zeile 282:
 
uservalues.service = newvalues
 
uservalues.service = newvalues
 
end -- end of if _CFG.control.validateParamService then
 
end -- end of if _CFG.control.validateParamService then
+
 
 +
-- derive linked portal pages from technical services
 +
uservalues._portal = getPortalListFor( uservalues.service )
 +
 
 
return uservalues
 
return uservalues
 
end
 
end
Zeile 167: Zeile 291:
 
function article.storeSementicData(uservalues)
 
function article.storeSementicData(uservalues)
 
 
local singlevalues = {}
+
local smwData = {}
 
for arg, prop in pairs(_CFG.arg2prop) do
 
for arg, prop in pairs(_CFG.arg2prop) do
if _TT.inTable(_CFG.multivalues, arg) then
+
smwData[prop] = uservalues[arg]
if uservalues[arg] then
 
_SMWUTIL.set(prop, uservalues[arg])
 
end
 
else
 
singlevalues[prop] = uservalues[arg]
 
end
 
 
end
 
end
-- handling of special property special property "has sortkey"
+
-- handling of special property "has sortkey"
 
if uservalues.disambiguation and #uservalues.disambiguation > 0 then
 
if uservalues.disambiguation and #uservalues.disambiguation > 0 then
singlevalues['has sortkey'] = uservalues.disambiguation .. '~' .. mw.title.getCurrentTitle().text
+
smwData['has sortkey'] = uservalues.disambiguation .. ' ' .. mw.title.getCurrentTitle().text
 
else
 
else
singlevalues['has sortkey'] = mw.title.getCurrentTitle().text
+
smwData['has sortkey'] = mw.title.getCurrentTitle().text
 
end
 
end
 
if uservalues.pagetype and #uservalues.pagetype > 0 then
 
if uservalues.pagetype and #uservalues.pagetype > 0 then
singlevalues['is disambiguation page'] = 1
+
smwData['is disambiguation page'] = 1
 
else
 
else
singlevalues['is disambiguation page'] = 0
+
smwData['is disambiguation page'] = 0
 
end
 
end
 
 
_SMWUTIL.set(singlevalues)
+
_SMWUTIL.set(smwData)
 +
-- debug:
 +
--return '<pre>\nuservalues:\n' .. _TT.printTable(uservalues) .. '\n\nsmwData:' .. _TT.printTable(smwData) .. '</pre>'
 
end
 
end
  
 
function article.infobox(uservalues)
 
function article.infobox(uservalues)
local frame = mw.getCurrentFrame()
 
 
 
-- "calculate" type of infobox
 
-- "calculate" type of infobox
 
local ib_type = getArticleInfoboxType(uservalues.os)
 
local ib_type = getArticleInfoboxType(uservalues.os)
  
-- "convert" the technical services in service portals
+
-- copy uservalues into local data tables
local services = {}
+
local os = mw.clone( uservalues.os )
+
local portal = mw.clone( uservalues._portal )
for _, s in pairs(uservalues.service) do
+
 
if not _TT.inTable(_CFG.defaultValues.service, s) then
+
table.sort(os)
table.insert(services, frame:expandTemplate{ title = s } )
+
table.sort(portal)
else
+
 
table.insert(services, _CFG.control.displayDefaultAs)
 
end
 
end
 
 
if uservalues.os and #uservalues.os > 0 then
 
for k, v in pairs(uservalues.os) do
 
if _TT.inTable(_CFG.defaultValues.os, v) then
 
uservalues.os[k] = _CFG.control.displayDefaultAs
 
else
 
uservalues.os[k] = '[[' .. v .. ']]'
 
end
 
end
 
else
 
uservalues.os = {'None'}
 
end
 
 
 
local ib_args = {
 
local ib_args = {
 
bodyclass = '',
 
bodyclass = '',
Zeile 231: Zeile 333:
 
header1 = "Informationen",
 
header1 = "Informationen",
 
label2 = 'Betriebssystem',
 
label2 = 'Betriebssystem',
data2 = mw.text.listToText(uservalues.os, ', ', ' und ') or '',--(uservalues.os and #uservalues.os > 0) and '[[' .. mw.text.listToText(uservalues.os, ']], [[', ']] und [[') .. ']]' or '',
+
data2 = printList( os, true ),
 
label3 = 'Service',
 
label3 = 'Service',
data3 = mw.text.listToText(services), --'[[' .. mw.text.listToText(uservalues.service, ']], [[', ']] und [[') .. ']]',
+
data3 = printList( portal, true, 'keine' ),
 
label4 = 'Interessant für',
 
label4 = 'Interessant für',
data4 = mw.text.listToText(uservalues.targetgroup, ', ', ' und '),
+
data4 = printList( uservalues.targetgroup ),
 
header6 = _CFG.ibCoreData[ib_type].portal
 
header6 = _CFG.ibCoreData[ib_type].portal
 
}
 
}
 
return _INFOBOX(ib_args)
 
return _INFOBOX(ib_args)
 +
end
 +
 +
function article.addBreadcrumbData( uservalues )
 +
if not _CFG.control.idForParentField then
 +
return ''
 +
end
 +
local findNonDefault = function( dataList )
 +
if type( dataList ) ~= 'table' then
 +
return false
 +
end
 +
for _, v in pairs( dataList ) do
 +
if not _CFG.fallBack2default[v] then
 +
return v
 +
end
 +
end
 +
end
 +
 +
local portal = uservalues._portal
 +
local parent = findNonDefault( portal )
 +
if not parent then
 +
parent = findNonDefault( uservalues.os )
 +
end
 +
if not parent and uservalues.disambiguation and #uservalues.disambiguation > 0 then
 +
parent = uservalues.disambiguation
 +
end
 +
if not parent then
 +
return ''
 +
else
 +
return '<span id="' .. _CFG.control.idForParentField .. '" style="display:none">' .. parent .. '</span>'
 +
end
 
end
 
end
  
Zeile 248: Zeile 380:
 
local category = '[[Category:' .. cat .. ']]'
 
local category = '[[Category:' .. cat .. ']]'
 
return category
 
return category
 +
end
 +
 +
function article.addDisplaytitle(uservalues)
 +
 +
if mw.title.getCurrentTitle().text == 'Oetterer' then
 +
return '<pre>' .. _TT.printTable( uservalues ) .. '</pre>'
 +
end
 +
 +
if not uservalues.displaytitle or #uservalues.displaytitle == 0 then
 +
return '<span style="display:none">no displaytitle found: ' .. mw.title.getCurrentTitle().text .. '</span>'
 +
end
 +
mw.ext.displaytitle.set(uservalues.displaytitle)
 +
 +
return '<span style="display:none">set displaytitle to ' .. uservalues.displaytitle .. '</span>'
 
end
 
end
  
Zeile 286: Zeile 432:
 
local output = mw.html.create('')
 
local output = mw.html.create('')
 
if #errors == 0 then
 
if #errors == 0 then
article.storeSementicData(uservalues)
+
result = article.storeSementicData(uservalues)
 +
if result then
 +
-- only used in debug context
 +
output:wikitext(result)
 +
end
 +
end
 +
 
 +
if mw.title.getCurrentTitle().text == 'Oetterer' then
 +
output:wikitext( '<pre>' .. _TT.printTable( uservalues ) .. '</pre>' )
 +
end
 +
 
 +
output:wikitext( article.addBreadcrumbData( uservalues ) )
 +
:wikitext( article.infobox( uservalues ) )
 +
:wikitext( article.addDisplaytitle( uservalues ) )
 +
:wikitext( article.addCategory( uservalues ) )
 +
:node( article.addLinkToDisambiguation( uservalues ) )
 +
:node( article.addErrors() )
 +
 
 +
if mw.title.getCurrentTitle().text == 'Oetterer' then
 +
output:wikitext( '<pre>' .. _TT.printTable( uservalues ) .. '</pre>' )
 
end
 
end
  
output:wikitext(article.infobox(uservalues))
 
:wikitext(article.addCategory(uservalues))
 
:node(article.addLinkToDisambiguation(uservalues))
 
:node(article.addErrors())
 
  
 
-- when {{article}} is called by {{disambiguation}} you need to: {{#ifeq:{{#var:disambiguate_isdisambiguation|0}}|1||{{#set:Is disambiguation=0}}}}
 
-- when {{article}} is called by {{disambiguation}} you need to: {{#ifeq:{{#var:disambiguate_isdisambiguation|0}}|1||{{#set:Is disambiguation=0}}}}

Version vom 12. März 2021, 13:13 Uhr

Documentation icon Module documentation
This module implements template {{Article}}. Configuration is stored in Module:Article/config.

Usage[Quelltext bearbeiten]

{{#invoke:Article|main}}

local getArgs = require('Module:Arguments').getArgs
local _INFOBOX = require('Module:Infobox').infobox
local _CFG = mw.loadData('Modul:Article/config')
local _TT = require('Module:TableTools')
local _SMWUTIL = require('Module:SmwUtil')

local article = {}
local errors = {}
local os2osfamily = {}

function getPagesInCategory(category)
	if category and #category > 0 then
		local result = _SMWUTIL.ask({select = '[[Category:' .. category .. ']]', fields = {}}, { mainlabel = 'pageName' } )
		local ret = {}
		for _, v in pairs(result) do
			if v.pageName and #v.pageName > 0 then
				ret[v.pageName] = v.pageName
			end
		end
		return ret
	else
		return nil
	end
end

function getOs2osfamily()
	if #os2osfamily == 0 then
		local result = _SMWUTIL.ask({ select = '[[Category:Betriebssysteme]]', fields = 'is member of os family#-=family' }, { mainlabel = 'pageName' })
		if not result or _TT.size(result) == 0 then
			os2osfamily = _CFG.os2osfamily
		else
			for _, osdata in pairs(result) do
				if osdata.pageName and osdata.family then
					os2osfamily[mw.ustring.lower(osdata.pageName)] = mw.ustring.lower(osdata.family)
					os2osfamily[osdata.pageName] = mw.ustring.lower(osdata.family)
				end
			end
		end
	end
	return os2osfamily
end

function getArticleInfoboxType(uservalues_os)
	if #os2osfamily == 0 then
		if _CFG.control.useAutomatedOsFamilyDetection then
			os2osfamily = getOs2osfamily()
		else
			os2osfamily = _CFG.os2osfamily
		end
	end

	local families = {}
	local ibType
	for _, os in pairs(uservalues_os) do
		if os2osfamily[mw.ustring.lower(os)] then
			families[os2osfamily[mw.ustring.lower(os)]] = 1
			ibType = os2osfamily[mw.ustring.lower(os)]
		else
			families[_CFG.control.fallbackIBType] = 1
			ibType = _CFG.control.fallbackIBType
		end
	end
	if _TT.size(families) ~= 1 then
		return _CFG.control.fallbackIBType
	else
		return ibType
	end
end

function getPortalListFor( services )

	local validTechnicalServices = {}
	for _, s in pairs( services ) do
		if not _CFG.fallBack2default[s] then
			table.insert( validTechnicalServices, s )
		end
	end

	if #validTechnicalServices == 0 then
		return {}
	end

	-- now build the query string and execute it
	local query = {
		select = '[[' .. table.concat( validTechnicalServices, ']] OR [[' ) .. ']]',
		fields = { 'Shows on service landing page#-=portal' }
	}
	local result = _SMWUTIL.ask( query, { mainlabel = 'service' } )

	-- build the lookup
	local portalsLookup = {}
	for _, row in pairs( result ) do
		if type( row.portal ) ~= 'table' then
			row.portal = { row.portal }
		end
		portalsLookup[row.service] = row.portal
		portalsLookup[mw.ustring.lower(row.service)] = row.portal
	end

	-- why use this loop instead of processing the query result directly?
	-- for the breadcrumb I want to prioritize services, so the parent
	-- is derived from the first entered service.
	-- Therefore I must base all my calculations on the original order
	-- of services instead of the query order

	local alreadyProcessed = {}
	local portalList = {}
	for _, service in pairs( services ) do
		if portalsLookup[service] then
			for _, v in pairs( portalsLookup[service] ) do
				if not alreadyProcessed[v] then
					table.insert( portalList, v )
					alreadyProcessed[v] = true
				end
			end
		elseif _CFG.fallBack2default[service]
			and not alreadyProcessed[_CFG.control.displayDefaultAs]
		then
			table.insert( portalList, _CFG.control.displayDefaultAs )
			alreadyProcessed[_CFG.control.displayDefaultAs] = true
		end
	end

	return portalList
end

function printList( list, link, default )
	if not list or _TT.size( list ) == 0 then
		return default or ''
	end
	if not link then
		return mw.text.listToText( list, ', ', ' und ' )
	end
	local linkedList = {}
	local insertDefault = true
	for _, v in pairs( list ) do
		if not _CFG.fallBack2default[v] then
			table.insert( linkedList, '[[' .. v .. ']]' )
		elseif insertDefault then
			table.insert( linkedList, _CFG.control.displayDefaultAs )
			insertDefault = false
		end
	end
	return mw.text.listToText( linkedList, ', ', ' und ' )
end

function split(str, sep)
	if type(str) == 'table' then
		return str
	end
	local r = {}
	if not sep then
		sep = ','
	end
	if str then
		for v in mw.text.gsplit(str, sep, true) do
			s = mw.text.trim(v)
			if mw.ustring.len(s) > 0 then
				table.insert(r, s)
			end
		end
	end
	if #r == 0 then
		r = nil
	end
	return r
end

function article.processArgs(args)
	--[[
		This method takes the user provided arguments and
		* checks all mandatory requirements
		* converts all multivalue parameters to tables
		* checks all provided valid entries
		* sets default values for non mandatory and not provided parameters
		* adds a preceeding 'Service:' to service if omitted
		f
		************** NOTE:
		The following parameters will optionally be checked for validity:
		* os
		* service
		see Modul:Article/config table control for more information
	--]]
	local uservalues = {}
	for _, arg in pairs(_CFG.allParams) do
		if _TT.inTable(_CFG.mandatory, arg) and (not args[arg] or #args[arg] == 0) then
			table.insert(errors, "Pflichtfeld ''" .. arg .. "'' fehlt!")
		elseif _TT.inTable(_CFG.multivalues, arg) then	-- process multivalue parameters (can assume that mandatory fields are set)
			if args[arg] and #args[arg] > 0 then	-- multivalue parameter is set, so proceed
				local valid = {}
				local invalid = {}
				if _CFG.validValues[arg] then
					-- we only have valid values for type and targetgroup
					for _, v in pairs(split(args[arg])) do	-- for every entry, check if it is valid
						if _TT.inTable(_CFG.validValues[arg], v) then
							table.insert(valid, v)
						else
							table.insert(invalid, v)
						end
					end
				else	-- of if _CFG.validValues[arg] then
					-- os and service can be validated later, if requested
					valid = split(args[arg])
				end	-- of if _CFG.validValues[arg] then .. else
				uservalues[arg] = valid
				if #invalid > 0 then
					table.insert(errors, "Parameter ''" .. arg .. "'' hat einen ungültigen Wert: " .. mw.text.listToText(invalid) .. "!")
				end
			else	-- multivalue parameter is not set, take default (which can be nil)
				uservalues[arg] = _TT.shallowClone(_CFG.defaultValues[arg])
			end
		else	-- process singlevalue parameters (can assume that mandatory fields are set)
			if not args[arg] or #args[arg] == 0 then	-- if not set, take default (which can be nil)
				uservalues[arg] = mw.clone(_CFG.defaultValues[arg])
			elseif _CFG.validValues[arg] and not _TT.inTable(_CFG.validValues[arg], args[arg]) then
				table.insert(errors, "Parameter ''" .. arg .. "'' hat einen ungültigen Wert: " .. args[arg] .. "!")
			else
				uservalues[arg] = args[arg]
			end	-- of if not args[arg] or #args[arg] == 0 then .. elseif .. else
		end	-- of if _TT.inTable(_CFG.mandatory, arg) and (not args[arg] or #args[arg] == 0) then .. elseif .. else
	end	-- of for _, arg in pairs(_CFG.allParams) do

	-- special processing of service field. see to it, that all entries have a preceeding 'Service:'
	for k, v in pairs(uservalues.service) do
		-- the following is for backwards compatibilty when we migrated services from ns meta to ns service
		if mw.ustring.find(v, 'Meta:', 1, true) then
			-- this is due to legacy reasons. service entites were once stored in namespace meta
			uservalues.service[k] = mw.ustring.gsub(v, 'Meta', 'Service', 1)
		elseif not mw.ustring.find(v, 'Service:', 1, true) then
			uservalues.service[k] = 'Service:' .. v
		end
	end
	
	-- if requested, do some plausibility checks
	if _CFG.control.validateParamOs then
		-- valid_od is an associative list os -> osfamily. here, os is present as queried and in lowercase
		local valid_os = getOs2osfamily()
		local newvalues = {}
		local fallingBack2default = nil
		for _, os in pairs(uservalues.os) do
			if not valid_os[mw.ustring.lower(os)] then
				-- this could happen, if user manually added one of the fallback defaults
				if _CFG.fallBack2default[os] then
					if not fallingBack2default then
						table.insert(newvalues, _CFG.defaultValues.os[1])
						fallingBack2default = true
					end
				else
					table.insert(errors, "Parameter ''os'' hat einen ungültigen Wert: '" .. os .. "'!")
				end
			else
				table.insert(newvalues, os)
			end	-- of if not valid_os[os] then
		end	-- of for _, os in pairs(uservalues.os) do
		uservalues.os = newvalues
	end	-- of if _CFG.control.validateParamOs then

	if _CFG.control.validateParamService then
		local valid_service = getPagesInCategory('Services')
		local inactive_service = getPagesInCategory('Inactive services')
		-- this is an associative list service -> service, whereas service is a pagename in ns service, e.g. Service:Mail
		local all_services = valid_service
		for k,v in pairs(inactive_service) do
			all_services[k] = v
		end
		local newvalues = {}
		local fallingBack2default = nil
		for _, service in pairs(uservalues.service) do
			if not all_services[service] then
				if _CFG.fallBack2default[service] then
					if not fallingBack2default then
						table.insert(newvalues, _CFG.defaultValues.service[1])
						fallingBack2default = true
					end
				else
					table.insert(errors, "Parameter ''service'' hat einen ungültigen Wert: '" .. service .. "'!")
				end
			else
				table.insert(newvalues, service)
			end	-- of if not valid_service[service] then
		end	-- of for _, service in pairs(uservalues.service) do
		uservalues.service = newvalues
	end	-- end of if _CFG.control.validateParamService then

	-- derive linked portal pages from technical services
	uservalues._portal = getPortalListFor( uservalues.service )

	return uservalues	
end

function article.storeSementicData(uservalues)
	
	local smwData = {}
	for arg, prop in pairs(_CFG.arg2prop) do
		smwData[prop] = uservalues[arg]
	end
	-- handling of special property "has sortkey"
	if uservalues.disambiguation and #uservalues.disambiguation > 0 then
		smwData['has sortkey'] = uservalues.disambiguation .. '  ' .. mw.title.getCurrentTitle().text
	else
		smwData['has sortkey'] = mw.title.getCurrentTitle().text
	end
	if uservalues.pagetype and #uservalues.pagetype > 0 then
		smwData['is disambiguation page'] = 1
	else
		smwData['is disambiguation page'] = 0
	end
	
	_SMWUTIL.set(smwData)
	-- debug:
	--return '<pre>\nuservalues:\n' .. _TT.printTable(uservalues) .. '\n\nsmwData:' .. _TT.printTable(smwData) .. '</pre>'
end

function article.infobox(uservalues)
	-- "calculate" type of infobox
	local ib_type = getArticleInfoboxType(uservalues.os)

	-- copy uservalues into local data tables
	local os = mw.clone( uservalues.os )
	local portal = mw.clone( uservalues._portal )

	table.sort(os)
	table.sort(portal)

	local ib_args = {
		bodyclass = '',
		aboveclass = 'objtitle titletext',
		title = uservalues.type,
		above = _CFG.ibCoreData[ib_type].image .. ' ' .. _CFG.ibCoreData[ib_type].label,
		headerclass = 'headertext',
		labelstyle = 'width: 30%;',
		datastyle = 'width: 70%;',
		header1 = "Informationen",
		label2 = 'Betriebssystem',
		data2 = printList( os, true ),
		label3 = 'Service',
		data3 = printList( portal, true, 'keine' ),
		label4 = 'Interessant für',
		data4 = printList( uservalues.targetgroup ),
		header6 = _CFG.ibCoreData[ib_type].portal
	}
	return _INFOBOX(ib_args)
end

function article.addBreadcrumbData( uservalues )
	if not _CFG.control.idForParentField then
		return ''
	end
	local findNonDefault = function( dataList )
		if type( dataList ) ~= 'table' then
			return false
		end
		for _, v in pairs( dataList ) do
			if not _CFG.fallBack2default[v] then
				return v
			end
		end
	end

	local portal = uservalues._portal
	local parent = findNonDefault( portal )
	if not parent then
		parent = findNonDefault( uservalues.os )
	end
	if not parent and uservalues.disambiguation and #uservalues.disambiguation > 0 then
		parent = uservalues.disambiguation
	end
	if not parent then
		return ''
	else
		return '<span id="' .. _CFG.control.idForParentField .. '" style="display:none">' .. parent .. '</span>'
	end
end

function article.addCategory(uservalues)
	if mw.title.getCurrentTitle().namespace ~= 0 then
		return ''
	end
	local cat = _CFG.type2category[uservalues.type] or _CFG.control.fallBackCategory
	local category = '[[Category:' .. cat .. ']]'
	return category
end

function article.addDisplaytitle(uservalues)

	if mw.title.getCurrentTitle().text == 'Oetterer' then
		return '<pre>' .. _TT.printTable( uservalues ) .. '</pre>'
	end

	if not uservalues.displaytitle or #uservalues.displaytitle == 0 then
		return '<span style="display:none">no displaytitle found: ' .. mw.title.getCurrentTitle().text .. '</span>'
	end
	mw.ext.displaytitle.set(uservalues.displaytitle)

	return '<span style="display:none">set displaytitle to ' .. uservalues.displaytitle .. '</span>'
end

function article.addErrors()
	local errorBoxes = mw.html.create('')
	if #errors > 0 then
		local messageBox = require('Module:Message box')
		for _, errortext in pairs(errors) do
			errorBoxes:wikitext(messageBox.main( 'ambox', {
						type = 'delete',
    					text = errortext
    					-- More parameters...
				})
			)
		end
		if mw.title.getCurrentTitle().namespace == 0 then
			errorBoxes:wikitext('[[Category:' .. _CFG.control.errorCategory .. ']]')
		end
	end
	return errorBoxes
end


function article.addLinkToDisambiguation(uservalues)
	local disambigLink = mw.html.create('')
	
	if uservalues.disambiguation and #uservalues.disambiguation > 0 then
		local hatnote = require('Module:Hatnote')._hatnote
		disambigLink:wikitext(hatnote(_CFG.hatnote .. ' [[' .. uservalues.disambiguation .. ']]', {}))
	end
	
	return disambigLink
end


function article._main(args)
	local uservalues = article.processArgs(args)
	local output = mw.html.create('')
	if #errors == 0 then
		result = article.storeSementicData(uservalues)
		if result then
			-- only used in debug context
			output:wikitext(result)
		end
	end

	if mw.title.getCurrentTitle().text == 'Oetterer' then
		output:wikitext( '<pre>' .. _TT.printTable( uservalues ) .. '</pre>' )
	end

	output:wikitext( article.addBreadcrumbData( uservalues ) )
		:wikitext( article.infobox( uservalues ) )
		:wikitext( article.addDisplaytitle( uservalues ) )
		:wikitext( article.addCategory( uservalues ) )
		:node( article.addLinkToDisambiguation( uservalues ) )
		:node( article.addErrors() )

	if mw.title.getCurrentTitle().text == 'Oetterer' then
		output:wikitext( '<pre>' .. _TT.printTable( uservalues ) .. '</pre>' )
	end


	-- when {{article}} is called by {{disambiguation}} you need to: {{#ifeq:{{#var:disambiguate_isdisambiguation|0}}|1||{{#set:Is disambiguation=0}}}}
	-- --> maybe its enough, to not have it set at all... {{#set:Is disambiguation=1}} is done by {{disambiguate}}
	return tostring(output)
end

function article.main(frame)
	local args = getArgs(frame)
	return article._main(args)
end

return article
Cookies helfen uns bei der Bereitstellung des IMT HilfeWikis. Bei der Nutzung vom IMT HilfeWiki werden die in der Datenschutzerklärung beschriebenen Cookies gespeichert.