« Module:Infobox » : différence entre les versions

De Starfield Wiki
Page créée avec « local p = {} --Chargement des informations des données passés au modèle et des variables globales -- données concernant les paramètres passés au modèle local localdata = {} -- données concernant la page où est affichée l'infobox local page = { name = mw.title.getCurrentTitle().prefixedText, namespace = mw.title.getCurrentTitle().namespace } local abb = require('Module:Abréviation') -- l'objet principal à retourner local infobox = mw.htm... »
(Aucune différence)

Version du 18 juillet 2022 à 21:01

Documentation[voir] [modifier] [purger]

Ce module génère une infobox à partir d'un sous-module de paramétrage. Il s'agit d'une version simplifiée de Module:Infobox présent sur Wikipédia.

Créer une infobox

Pour créer une nouvelle infobox, il faut déclarer son paramétrage comme sous-module du module Infobox. Par exemple, si on souhaite créer Infobox Planète alors on déclarera son paramétrage dans Module:Infobox/Planète.

Le sous-module doit retourner une table contenant la structure de l'infobox.

local p = {}

--[[
	Chargement des informations des données passés au modèle et des variables globales
]]

-- données concernant les paramètres passés au modèle
local localdata = {}

-- données concernant la page où est affichée l'infobox
local page = {
	name = mw.title.getCurrentTitle().prefixedText,
	namespace =  mw.title.getCurrentTitle().namespace
}

local abb = require('Module:Abréviation')

-- l'objet principal à retourner
local infobox = mw.html.create('div')

local i18n = {
	['see doc'] = 'Documentation du modèle',
	['edit'] = 'modifier',
	['edit code'] = 'modifier le code',
	['edit item'] = 'modifier Wikidata',
	['tracking cat'] = "Page utilisant des données de Wikidata",
	['invalid block type'] = "Bloc de données invalide dans le module d'infobox",
	['default cat'] = "Maintenance des infobox",
}

--[[
	Outils
]]

local function getValue(value, part)
	if type(value) == 'string' then
		return localdata[value]
	elseif type(value) == 'function' then
		return value(localdata, part)
	elseif type(value) == 'table' then
        -- si plusieurs paramètres possibles (legacy de vieux code), prendre le premier non vide
		for i, j in pairs(value) do
			if localdata[j] then
				return localdata[j]
			end
		end
	end
end

function p.separator()
	return mw.html.create('hr'):addClass('separator')	
end

--[[
	Construction des blocs
]]

function p.buildtitle(part)
	local text = getValue(part.value, part) or part.textdefaultvalue or mw.title.getCurrentTitle().text
	local subtext = getValue(part.subtitle, part) or part.subtitledefaultvalue
	
	text = mw.ustring.gsub(text, " [(][^()]*[)]$", "")
	
	if subtext and (subtext ~= text) then
		text = text .. '<br /><small>' .. subtext .. '</small>'
	end
	local class = 'avt-infobox-header'
	
    local style = {}
	if part.style then
		for i, j in pairs(part.style) do
			style[i] = j
		end
	end
	
	local icon = getValue(part.icon, part) or nil
	if icon then
		icon = tostring(mw.html.create('div')
			:addClass('avt-infobox-header-icon')
			:wikitext('[[Fichier:'..icon..'|30x30px|alt=|link=]]')
			:allDone())
	end
	
	local subhead = nil
	if part.subhead then
		local subheadText = abb.links({
			getValue(part.subhead.games, part),
			part.subhead.link,
			part.subhead.subject
		})
		if subheadText then
			subhead = tostring(mw.html.create('div')
				:addClass('avt-infobox-header-subhead')
				:wikitext(subheadText)
				:allDone())
		end
	end

	local title = mw.html.create('div')
		:addClass(class)
		:css(style)
		:node(icon)
		:node(subhead)
		:tag('div')
			:addClass('avt-infobox-header-title')
			:wikitext(text)
		:allDone()
	
	return title
end
p.buildTitle = p.buildtitle

function p.buildimages(part)
	local images = {}
	local upright, link, caption, alt
	if type(part.imageparameters) == 'string' then
		part.imageparameters = { part.imageparameters }
	end
	if not part.imageparameters then -- s'il n'y a pas de paramètre image, continuer, peut-être y a-t-il une image par défaut définie dans le module d'infobox
		part.imageparameters = {}
	end
	for j, k in ipairs(part.imageparameters) do
		table.insert(images, localdata[k])
	end

	-- Images par défaut
	if #images == 0 then
--		if part.maintenancecat then
--			addMaintenanceCat(part.maintenancecat, part.sortkey)
--		end
		if part.defaultimages then
			images = part.defaultimages
			if type(images) == 'string' then
				images = { images }
			end
			upright = part.defaultimageupright
			caption = part.defaultimagecaption
			link = part.defaultimagelink
			alt = part.defaultimagealt
			if not alt then
				alt = 'une illustration pour cette infobox serait bienvenue'
			end
		end
	end
	
	if #images == 0 then
		return nil
	end
	
	upright = upright or getValue(part.uprightparameter) or part.defaultupright or "1.2"
	link = link or getValue(part.linkparameter) or part.defaultlink
	caption = caption or getValue(part.captionparameter) or part.defaultcaption
	alt = alt or getValue(part.altparameter) or part.defaultalt
	
	if tonumber(upright) then
		upright = tostring( tonumber(upright) / #images )
	end

	local style = part.style or {}

	-- Partie image

	local imagesString = ''
	for i,image in pairs(images) do
		if image == '-' then
			return
		end
		imagesString = imagesString ..  '[[Fichier:' .. image .. '|frameless'
		if alt then
			imagesString = imagesString .. '|alt=' .. alt
		end
		if link then
			imagesString = imagesString .. '|link=' .. link
		end
		if upright then
			imagesString = imagesString .. '|upright=' .. upright
		elseif #images > 1 then
			imagesString = imagesString .. '|upright=' .. ( 1 / #images )
		end
		imagesString = imagesString .. ']]'
	end

	local image = mw.html.create('div')
		:addClass("avt-infobox-images")
		:css(style)
		:wikitext(imagesString)

	-- Partie légende
	local captionobj
	if caption then
		captionobj = mw.html.create('div')
			:wikitext(caption)
			:css(part.legendstyle or {})
			:addClass("avt-infobox-images-legend")
			:done()
	end
	
	-- séparateur
	local separator
	if part.separator then
		separator = separator(part)
	end
	return mw.html.create('div')
		:node(image)
		:node(captionobj)
		:node(separator)
		:done()
end
p.buildImages = p.buildimages

function p.buildtext(part)
	local class = part.class or ''
	local style = {
		['text-align'] = 'center',
		['font-weight'] = 'bold'
	}
	if part.style then
		for i, j in pairs(part.style) do
			style[i] = j
		end
	end
	local text = getValue(part.value, part) or part.defaultvalue
	if text == '-' then
		return
	end
	if not text then
		--addMaintenanceCat(part.maintenancecat, part.sortkey)
		return nil
	end
	local formattedtext = mw.html.create('p')
		:addClass(class)
		:css(style)
		:wikitext(text)
		:done()
	return formattedtext
end
p.buildText = p.buildtext

function p.buildrow(part)
	local class = part.class or ''
	local style = part.style or {}
	local valueClass = part.valueClass or ''
	local valueStyle = part.valueStyle or {}
	local value, number = getValue(part.value, part)
	
	if not value then
		value = part.defaultvalue
	end
	if value == nil then
		return nil
	end
	if not number then
		number = 0 -- == indéfini
	end

--	if not value then
--		if part.maintenancecat then
--			local maintenancecat = getValue(part.maintenancecat, part)
--			addMaintenanceCat(maintenancecat, part.sortkey)
--		end
--		return nil
--	end

	local label = part.label
	if number > 1 and part.plurallabel then
		label = part.plurallabel
	elseif number == 1 and part.singularlabel then
		label = part.singularlabel
	end
	if type(label) == 'function' then
			label = label(localdata, localdata.item)
	end

	-- format
	local formattedvalue = mw.html.create('div')
		:wikitext('\n' .. value) -- Le '\n' est requis lorsque value est une liste commençant par '*' ou '#'
		
	if part.hidden == true then
		formattedvalue
			:attr({class="NavContent", style="display: none; text-align: left;"})
		formattedvalue = mw.html.create('div')
			:attr({class="NavFrame", title="[Afficher]/[Masquer]", style="border: none; padding: 0;"})
			:node(formattedvalue)
	end
	formattedvalue =  mw.html.create('td')
			:node(formattedvalue)
			:addClass(valueClass)
			:css(valueStyle)
			:allDone()
	
	local formattedlabel
	if label then
		formattedlabel = mw.html.create('th')
			:attr('scope', 'row')
			:wikitext(label)
			:done()
	end
	local row = mw.html.create('tr')
		:addClass(class)
		:css(style)
		:node(formattedlabel)
		:node(formattedvalue)
		:done()
	
	return row
end
p.buildRow = p.buildrow

function p.buildsuccession(part)
	if not part.value then
		return nil
	end
	
	local values = part.value
	local before = getValue(values['before'], part)
	local center = getValue(values['center'], part)
	local after  = getValue(values['after'], part)
	
	if not before and not center and not after then
		return nil
	end
		
	--local style = part.style or {}
	--style['text-align'] = style['text-align'] or 'center'
	--style['color'] = style['color'] or '#000000'
	--style['background-color'] = style['background-color'] or '#F9F9F9'
	
	local rowI = mw.html.create('tr')
	
	local styleI = {}
	local colspan = '2'
	styleI['padding'] = '1px'
	cellI = mw.html.create('td')
			:attr({colspan = colspan})
			:attr({align = 'center'})
			:css(styleI)
	
	local styleT = {}
	styleT['margin'] = '0px'
	styleT['background-color'] = 'transparent'
	styleT['width'] = '100%'
	tabC = mw.html.create('table')
			:attr({cellspacing = '0'})
			:addClass('navigation-not-searchable')
			:css(styleT)
	
	local row = mw.html.create('tr')

	local color = part.color

	local style = {}
	local arrowLeft
	local arrowRight
	
	if color == 'default' then
		arrowLeft = '[[Fichier:SCRWEST.png|13px|alt=Précédent|link=]]'
		arrowRight = '[[Fichier:SCREAST.png|13px|alt=Suivant|link=]]'
	else
		arrowLeft = '[[Fichier:SCRWEST.png|13px|alt=Précédent|link=]]'
		arrowRight = '[[Fichier:SCREAST.png|13px|alt=Suivant|link=]]'
		style['background-color'] = color
	end
	
	local styleTrans = {}
	
	local widthCell = '44%'
	if center then
		widthCenter = '28%'
		widthCell = '29%'
	end
	
	local formattedbefore
	if before then
		formattedbefore = mw.html.create('td')
			:attr({valign = 'middle'})
			:attr({align = 'left'})
			:attr({width = '5%'})
			:css(style)
			:wikitext(arrowLeft)
			:done()
		row:node(formattedbefore)
		formattedbefore = mw.html.create('td')
			:attr({width = '1%'})
			:css(style)
			:wikitext('')
			:done()
		row:node(formattedbefore)
		formattedbefore = mw.html.create('td')
			:attr({align = 'left'})
			:attr({valign = 'middle'})
			:attr({width = widthCell})
			:css(style)
			:wikitext(before)
			:done()
		row:node(formattedbefore)
	else
		formattedbefore = mw.html.create('td')
			:attr({valign = 'middle'})
			:attr({align = 'left'})
			:attr({width = '5%'})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedbefore)
		formattedbefore = mw.html.create('td')
			:attr({width = '1%'})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedbefore)
		formattedbefore = mw.html.create('td')
			:attr({align = 'left'})
			:attr({valign = 'middle'})
			:attr({width = widthCell})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedbefore)
	end
	
	local formattedcenter
	formattedcenter = mw.html.create('td')
		:attr({width = '1%'})
		:css(styleTrans)
		:wikitext('')
		:done()
	row:node(formattedcenter)
	
	if center then
		formattedcenter = mw.html.create('td')
			:attr({align = 'center'})
			:attr({valign = 'middle'})
			:attr({width = widthCenter})
			:css(style)
			:wikitext(center)
			:done()
		row:node(formattedcenter)
		formattedcenter = mw.html.create('td')
			:attr({width = '1%'})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedcenter)
	end
	
	local formattedafter
	if after then
		formattedafter = mw.html.create('td')
			:attr({align = 'right'})
			:attr({valign = 'middle'})
			:attr({width = widthCell})
			:css(style)
			:wikitext(after)
			:done()
		row:node(formattedafter)
		formattedbefore = mw.html.create('td')
			:attr({width = '1%'})
			:css(style)
			:wikitext('')
			:done()
		row:node(formattedbefore)
		formattedafter = mw.html.create('td')
			:attr({align = 'right'})
			:attr({valign = 'middle'})
			:attr({width = '5%'})
			:css(style)
			:wikitext(arrowRight)
			:done()
		row:node(formattedafter)
	else
		formattedafter = mw.html.create('td')
			:attr({align = 'right'})
			:attr({valign = 'middle'})
			:attr({width = widthCell})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedafter)
		formattedbefore = mw.html.create('td')
			:attr({width = '1%'})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedbefore)
		formattedafter = mw.html.create('td')
			:attr({align = 'right'})
			:attr({valign = 'middle'})
			:attr({width = '5%'})
			:css(styleTrans)
			:wikitext('')
			:done()
		row:node(formattedafter)
	end
	
	row:done()
	tabC:node(row)
	tabC:done()
	cellI:node(tabC)
	cellI:done()
	rowI:node(cellI)
	rowI:allDone()
	
	return rowI
end
p.buildSuccession = p.buildsuccession

function p.buildrow1col(part)
	if not part.value then
		return nil
	end

	local class = 'row1col'
	if part.class then
		class = class .. ' ' .. part.class
	end
	
	local text = getValue(part.value, part)
	
	if not text then
		return nil
	end

	local formattedlabel
	formattedlabel = mw.html.create('th')
		:attr({ colspan = '2' })
		:addClass(class)
		:wikitext(text)
		:done()

	local row = mw.html.create('tr')
		:node(formattedlabel)
		:done()
	
	return row
end
p.buildRow1Col = p.buildrow1col

function p.buildtable(part)
	local class = nil
	if part.collapseparameters then
		if part.collapseparameters.collapsible == true then
			class = 'mw-collapsible'
			if part.collapseparameters.collapsed == true then
				class = class ..' mw-collapsed'
			end
		end
	end
	
	local tab = mw.html.create('table')
		:addClass(class)
		:css(part.style or {})

	local rows = part.rows
	
	-- expand parameters so that we have a list of tables
	local i = 1

	while (i <= #rows) do 
		local l = rows[i]
		if type(l) == 'function' then 
			l = l(localdata, localdata.item)
		end
		if (type(l) == 'table') and (l.type == 'multi') then
			table.remove(rows, i)  
			for j, row in ipairs(l.rows) do
				table.insert(rows, i + j - 1, row) 
			end
		elseif type(l) == 'nil' then
			table.remove(rows, i)
		elseif type(l) ~= 'table' then 
			return error('les lignes d\'infobox ("rows") doivent être des tables, est ' .. type(l))
		else
			i = i + 1
		end
	end 

	-- CREATE ROW
	local expandedrows = {}
	for k, row in ipairs(rows) do
		local v = p.buildblock(row)
		if v then
			table.insert(expandedrows, v)
		end
	end
	if (#expandedrows == 0) then
		return nil
	end
	rows = expandedrows

	-- ADD TITLE
	local title
	if part.title or part.singulartitle or part.pluraltitle then
		local text
		if #rows > 1 and part.pluraltitle then
			text = part.pluraltitle
		elseif #rows == 1 and part.singulartitle then
			text = part.singulartitle
		else
			text = part.title
		end

		local style = part.titlestyle or {}

		title = mw.html.create('caption')
			:attr({ colspan = '2' })
			:css(style)
			:wikitext(text)
			:done()
	end
	
	if title then
		tab:node(title)
	end
	
	for i, j in pairs (rows) do
		tab:node(j)
	end
	
	if part.separator then
		local separator = p.separator(part)
		tab:node(separator)
	end
	tab:allDone()
	return tab
end
p.buildTable = p.buildtable

function p.buildinvalidblock(args)
--	addMaintenanceCat(defaultcat)
	local text = ''
	if type(args) ~= 'table' then
		text = "Les blocs d'infobox doivent être des tables"
	else
		text = i18n["invalid block type"] .. ' : ' .. (args.type or '??')
	end
	return text
end
p.buildInvalidBlock = p.buildinvalidblock

--function p.buildexternaltext(part)
--	local value = getValue(part.value)
--	if value and (type(value) == 'string') then
--		externaltext = externaltext .. value
--	end
--end
--p.buildExternalText = p.buildexternaltext



--[[
	Construction de l'infobox
]]

function p.buildblock(block)
	if type(block) == 'function' then
		block = block(localdata)
	end

	 -- list of functions for block buildings
	local blocktypes = {
		['invalid'] = p.buildinvalidblock,
--		['external text'] = p.buildexternaltext,
		['images'] = p.buildimages,
		['mixed'] = p.buildrow,
--		['navbox'] = p.buildnavbox,
		['table'] = p.buildtable,
		['row'] = p.buildrow,
		['row1col'] = p.buildrow1col,
		['succession'] = p.buildsuccession,
		['text'] = p.buildtext,
		['title'] = p.buildtitle,
	}
	if type(block) ~= 'table' or (not block.type) or (not blocktypes[block.type]) then
		return blocktypes['invalid'](block)
	end
	return blocktypes[block.type](block) 
end
p.buildBlock = p.buildblock

function p.build()
	localdata = require('Module:Infobox/Localdata')
	item = localdata.item

	-- chargement du module de paramétrage
	local moduledata = require('Module:Infobox/' .. localdata.modulename)
	moduledata.name = localdata.modulename
	
	-- class
	local class = 'infobox avt-infobox'
	if moduledata.class then
		class = class .. ' ' .. moduledata.class
	end

	-- style
	local style = moduledata.style or {}
	
	-- build infobox
	infobox	:addClass(class)
			:css(style)
	
	for i, j in pairs(moduledata.parts) do
		infobox:node(p.buildblock(j))
	end

	return tostring(infobox)
end

return p