Module:Infobox : Différence entre versions

De Lagny-sur-Marne Wiki
Aller à : navigation, rechercher
(build(frame))
(Annulation des modifications 124268579 de Flyshitt (d))
Ligne 1 : Ligne 1 :
--
 
-- This module implements {{Infobox}}
 
--
 
 
 
local p = {}
 
local p = {}
 +
local lang = 'fr'
 +
-- variables globales alimentées par les paramètres utilisés
 +
item = nil -- l'élément Wikidata lié
 +
moduledata = nil -- la sous-page de module:Infobox demandéep
 +
localdata = {}-- données concernant les paramètres passés au modèle
 +
page = { -- données concernant la page où est affichée l'infobox
 +
name = mw.title.getCurrentTitle().prefixedText,
 +
namespace =  mw.title.getCurrentTitle().namespace
 +
}
 +
local maincolor, secondcolor, thirdcolor = '#E1E1E1', '#E1E1E1', '#000000'
  
local navbar = require('Module:Navbar')._navbar
+
-- l'objet principal à retournerp
 +
local infobox = mw.html.create('div')
  
local args = {}
+
-- objes secondaires à retourner
local origArgs
+
local maintenance = '' -- chaîne retournfoée avec le module : cats de maintenance
local root
+
local externaltext = '' -- par exemple coordonnées en titre
 +
-- modules importés
 +
local wikidata = require('Module:Interface Wikidata').fromLua
 +
local wd = require 'Module:Wikidata'
 +
local defaultstyle = require "Module:Infobox/Style"
 +
local mapmod = require "Module:Carte"
  
local function union(t1, t2)
+
local i18n = {
    -- Returns the union of the values of two tables, as a sequence.
+
['see doc'] = 'Documentation du modèle',
    local vals = {}
+
['edit'] = 'modifier',
    for k, v in pairs(t1) do
+
['edit code'] = 'modifier le code',
        vals[v] = true
+
['edit item'] = 'modifier Wikidata',
    end
+
['tracking cat'] = "Page utilisant des données de Wikidata",
    for k, v in pairs(t2) do
+
['invalid block type'] = "Bloc de données invalide dans le module d'infobox",
        vals[v] = true
+
['default cat'] = "Maintenance des infobox",
    end
+
}
    local ret = {}
+
 
    for k, v in pairs(vals) do
+
local function addwikidatacat(prop)
        table.insert(ret, k)
+
maintenance = maintenance .. wikidata.addtrackingcat(prop)
    end
 
    return ret
 
 
end
 
end
  
local function getArgNums(prefix)
+
local function expandquery(query)
    -- Returns a table containing the numbers of the arguments that exist
+
local value, number -- valeur à retourner, nombre de valeurs pour accorder le libellé
    -- for the specified prefix. For example, if the prefix was 'data', and
+
if not query.entity then
    -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
+
query.entity = item
    local nums = {}
+
end
    for k, v in pairs(args) do
+
if not query.conjtype then
        local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
+
query.conjtype = 'comma'
        if num then table.insert(nums, tonumber(num)) end
+
end
    end
+
local claims = wikidata.getClaims(query)
    table.sort(nums)
+
if (not claims) then
    return nums
+
return nil
 +
end
 +
return wikidata.formatAndCat(query), #claims -- pour l'accord au pluriel
 
end
 
end
  
local function addRow(rowArgs)
+
local function getWikidataValue(params, wikidataparam)
    -- Adds a row to the infobox, with either a header cell
+
-- Récupère la valeur Wikidata pour la valeur, soit dans le paramètre "wikidata" soit dans le praramètre "property"
    -- or a label/data cell combination.
+
if not item then
    if rowArgs.header then
+
return nil
        root
+
end
            :tag('tr')
+
local value, number
                :addClass(rowArgs.rowclass)
+
                :cssText(rowArgs.rowstyle)
+
if not wikidataparam then -- par défaut la valeur wikidata est dans le paramètre "wikidata" mais dans les structures composées comme "title", il y a plusieurs paramètres wikidata
                :attr('id', rowArgs.rowid)
+
wikidataparam = 'wikidata'
                :tag('th')
+
end
                    :attr('colspan', 2)
+
 
                    :attr('id', rowArgs.headerid)
+
if params[wikidataparam] then
                    :addClass(rowArgs.class)
+
if type(params[wikidataparam]) == 'function' then
                    :addClass(args.headerclass)
+
return params[wikidataparam](item)
                    :css('text-align', 'center')
+
elseif type(params[wikidataparam]) == 'table' then
                    :cssText(args.headerstyle)
+
return expandquery(params[wikidataparam])
                    :wikitext(rowArgs.header)
+
else
    elseif rowArgs.data then
+
return params[wikidataparam]
        local row = root:tag('tr')
+
end
        row:addClass(rowArgs.rowclass)
+
end
        row:cssText(rowArgs.rowstyle)
 
        row:attr('id', rowArgs.rowid)
 
        if rowArgs.label then
 
            row
 
                :tag('th')
 
                    :attr('scope', 'row')
 
                    :attr('id', rowArgs.labelid)
 
                    :cssText(args.labelstyle)
 
                    :wikitext(rowArgs.label)
 
                    :done()
 
        end
 
       
 
        local dataCell = row:tag('td')
 
        if not rowArgs.label then  
 
            dataCell
 
                :attr('colspan', 2)
 
                :css('text-align', 'center')
 
        end
 
        dataCell
 
            :attr('id', rowArgs.dataid)
 
            :addClass(rowArgs.class)
 
            :cssText(rowArgs.datastyle)
 
            :newline()
 
            :wikitext(rowArgs.data)
 
    end
 
 
end
 
end
  
local function renderTitle()
+
local function getvalue(val, params)
    if not args.title then return end
+
if type(val) == 'string' then
 +
return localdata[val]
 +
elseif type(val) == 'function' then
 +
return val(localdata, item, params)
 +
elseif type(val) == 'table' then
 +
for i, j in pairs(val) do -- si plusieurs paramètres possibles (legacy de vieux code), prendre le preimeir non bide
 +
if localdata[j] then
 +
return localdata[j]
 +
end
 +
end
 +
end
 +
end
  
    root
+
local function addmaintenancecat(cat, sortkey)
        :tag('caption')
+
if page.namespace ~= 0 then
            :addClass(args.titleclass)
+
return ''
            :cssText(args.titlestyle)
+
end
            :wikitext(args.title)
+
if cat then
 +
maintenance = maintenance .. '[[Category:' .. cat .. '|' .. (sortkey or page.name) .. ']]'
 +
end
 
end
 
end
  
local function renderAboveRow()
+
function p.separator(params)
    if not args.above then return end
+
local style = params['separator style'] or {}
   
+
style.height = style.height or '2px'
    root
+
style['background-color'] = style['background-color'] or maincolor
        :tag('tr')
+
            :tag('th')
+
return mw.html.create('hr'):css( style )
                :attr('colspan', 2)
 
                :addClass(args.aboveclass)
 
                :css('text-align', 'center')
 
                :css('font-size', '125%')
 
                :css('font-weight', 'bold')
 
                :cssText(args.abovestyle)
 
                :wikitext(args.above)
 
 
end
 
end
  
local function renderBelowRow()
+
function p.buildtitle(params)
    if not args.below then return end
+
local text = getvalue(params.value, params) or params.textdefaultvalue or  getWikidataValue(params) or mw.title.getCurrentTitle().text
   
+
local subtext = getvalue(params.subtitle) or  getWikidataValue(params, 'wikidatasubtitle') or params.subtitledefaultvalue
    root
+
if subtext and (subtext ~= text) then
        :tag('tr')
+
text = text .. '<br /><small>' .. subtext .. '</small>'
            :tag('td')
+
end
                :attr('colspan', '2')
+
local icon = params.icon or ''
                :addClass(args.belowclass)
+
if icon ~= '' and not params.large then
                :css('text-align', 'center')
+
icon = 'icon ' .. icon
                :cssText(args.belowstyle)
+
end
                :newline()
+
local class = 'entete ' .. icon
                :wikitext(args.below)
+
 +
-- overwrites with those provided in the module
 +
local style = {}
 +
style['background-color'] = maincolor
 +
style['color'] = thirdcolor
 +
if params.style then
 +
for i, j in pairs(params.style) do
 +
style[i] = j
 +
end
 +
end
 +
local title = mw.html.create('div')
 +
:addClass(class)
 +
:css(style)
 +
:tag('div')
 +
:wikitext(text)
 +
:allDone()
 +
return title
 
end
 
end
  
local function renderSubheaders()
+
function p.buildnavbox(params)
    if args.subheader then
+
        args.subheader1 = args.subheader
+
-- définition du style
    end
+
local class = "overflow nav " .. (params.class or '')
    if args.subheaderrowclass then
+
local style = params.style or {}
        args.subheaderrowclass1 = args.subheaderrowclass
+
 
    end
+
if params.separated then -- options pour ajouter une ligne de séparation au dessus
    local subheadernums = getArgNums('subheader')
+
style['border-top'] = '1px solid' .. maincolor
    for k, num in ipairs(subheadernums) do
+
end
        addRow({
+
 
            data = args['subheader' .. tostring(num)],
+
-- ajustement des paramètres de données
            datastyle = args.subheaderstyle or args['subheaderstyle' .. tostring(num)],
+
params.previousval = params.previousval or params.previousparameter -- nom de paramètre obsolète
            class = args.subheaderclass,
+
params.nextval = params.nextval or params.nextparameter
            rowclass = args['subheaderrowclass' .. tostring(num)]
+
        })
+
if params.previousproperty then
    end
+
params.previouswikidata = {property = params.previousproperty}
 +
end
 +
if params.nextproperty then
 +
params.nextwikidata = {property = params.nextproperty}
 +
end
 +
 +
 
 +
local previousval = getvalue(params.previousval, params) or getWikidataValue(params, 'previouswikidata')
 +
local nextval = getvalue(params.nextval, params) or getWikidataValue(params, 'nextwikidata')
 +
 +
local navbox
 +
if params.inner then -- pour celles qui sont à l'intérieur d'une table
 +
navbox = mw.html.create('tr'):tag('th'):attr('colspan', 2)
 +
style['font-weight'] = style['font-weight'] or 'normal'
 +
else
 +
navbox = mw.html.create('div')
 +
end
 +
 +
navbox
 +
:addClass(class)
 +
:css(style)
 +
:tag('div')
 +
:addClass('prev_bloc')
 +
:wikitext(previousval)
 +
:done()
 +
:tag('div')
 +
:addClass('next_bloc')
 +
:wikitext(nextval)
 +
:done()
 +
:allDone()
 +
return navbox
 
end
 
end
  
local function renderImages()
+
function p.buildimages(params)
    if args.image then
+
local images = {}
        args.image1 = args.image
+
local upright, link, caption, size -- size is deprecated
    end
+
if type(params.imageparameters) == 'string' then
    if args.caption then
+
params.imageparameters = {params.imageparameters}
        args.caption1 = args.caption
+
end
    end
+
if not params.imageparameters then -- s'il n'y a pa de paramètre image, continuer, peut-être y-a-t-il une image par défaut définie dans le module d'infobox
    local imagenums = getArgNums('image')
+
params.imageparameters = {}
    for k, num in ipairs(imagenums) do
+
end
        local caption = args['caption' .. tostring(num)]
+
for j, k in ipairs(params.imageparameters) do
        local data = mw.html.create():wikitext(args['image' .. tostring(num)])
+
table.insert(images, localdata[k])
        if caption then
+
end
            data
+
                :tag('div')
+
-- Images de Wikidata
                    :cssText(args.captionstyle)
+
if #images == 0 and item then
                    :wikitext(caption)
+
if params.property then
        end
+
images = wikidata.getClaims{entity = item, property = params.property} or {}
        addRow({
+
if #images > 0 then
            data = tostring(data),
+
addwikidatacat(params.property)
            datastyle = args.imagestyle,
+
end
            class = args.imageclass,
+
end
            rowclass = args['imagerowclass' .. tostring(num)]
+
if params.wikidata then
        })
+
images = params.wikidata()
    end
+
if type(images) == 'string' then
 +
return images
 +
end -- c'est probablement une erreur dans la requête => afficher le message
 +
end
 +
end
 +
if type(images[1]) == 'table' then
 +
for i, j in pairs(images) do
 +
if j.mainsnak.snaktype ~= 'value' then
 +
return
 +
end
 +
local wdcaptions, wdcaption
 +
local q = images[i].qualifiers
 +
if q then
 +
wdcaptions = q['P2096']
 +
end
 +
if wdcaptions then
 +
for k, l in pairs(wdcaptions) do
 +
if l.datavalue.value and l.datavalue.value.language == lang then
 +
wdcaption = wd.formatSnak(l)
 +
end
 +
end
 +
end
 +
if wdcaption and caption then -- si deux légendes, désactivées pour éviter les conflits
 +
caption = nil
 +
elseif wdcaption then
 +
caption = wdcaption
 +
end
 +
if i > (params.numval) then
 +
images[i] = nil
 +
else
 +
images[i] = j.mainsnak.datavalue.value
 +
end
 +
end
 +
end
 +
 
 +
-- Images par défaut
 +
local isdefault = false
 +
if #images == 0 then
 +
if params.maintenancecat then
 +
local maintenancecat = getvalue(params.maintenancecat, params)
 +
if maintenancecat and maintenancecat ~= '-' then
 +
addmaintenancecat(maintenancecat, params.sortkey)
 +
end
 +
end
 +
if params.defaultimages then
 +
images = params.defaultimages
 +
if type(images) == 'string' then
 +
images = {images}
 +
end
 +
end
 +
upright, caption, link = params.defaultimageupright, params.defaultimagecaption, params.defaultimagelink
 +
end
 +
if #images == 0 then
 +
return nil
 +
end
 +
 +
upright = size or getvalue(params.uprightparameter) or params.defaultupright or "1.2"
 +
link = link or getvalue(params.linkparameter) or params.defaultlink
 +
caption = caption or getvalue(params.captionparameter) or params.defaultcaption or ''
 +
 
 +
if type(size) == 'function' then
 +
size = size(localdata)
 +
end
 +
if type(link) == 'function' then
 +
link = link()
 +
end
 +
if type(caption) == 'function' then
 +
caption = caption(localdata)
 +
end
 +
 
 +
-- taille avec "size" (obsolète)
 +
size = size or getvalue(params.sizeparameter) or params.defaultsize -- deprecated
 +
if size then
 +
local numsize = size:gsub('px', '')
 +
numsize = mw.ustring.gsub(numsize, 'x.*', '')
 +
numsize = tonumber(numsize)
 +
if type(numsize) ~= 'number' or numsize > 280 then
 +
addmaintenancecat("taille d'image invalide")
 +
end
 +
if tonumber(size) then
 +
size = size .. 'px'
 +
end
 +
size = '|' .. size
 +
else
 +
size = ''
 +
end
 +
 +
if link then
 +
link = '|link=' .. link
 +
else
 +
link = ''
 +
end
 +
local style = params.style or {padding ='2px 0',}
 +
 
 +
-- Partie image
 +
 
 +
local imagesString = ''
 +
for i,image in pairs(images) do
 +
if image == '-' then
 +
return
 +
end
 +
imagesString = imagesString ..  '[[Fichier:' .. image .. link .. '|frameless' .. size
 +
if #images == 1 then
 +
imagesString = imagesString .. '|center'
 +
end
 +
if upright then
 +
imagesString = imagesString .. '|upright=' .. upright
 +
else
 +
imagesString = imagesString .. '|upright=' .. ( 1 / #images )
 +
end
 +
imagesString = imagesString .. ']]'
 +
end
 +
 
 +
local image = mw.html.create('div')
 +
:addClass("images")
 +
:css(style)
 +
:wikitext(imagesString)
 +
 
 +
-- Partie légende
 +
local captionobj = mw.html.create('p')
 +
if caption then
 +
captionobj
 +
:wikitext(caption)
 +
:css(params.style or {})
 +
:addClass("legend")
 +
:done()
 +
end
 +
 +
-- séparateur
 +
local separator
 +
if params.separator then
 +
separator = separator(params)
 +
end
 +
return mw.html.create('div'):node(image):node(captionobj):node(separator):done()
 
end
 
end
  
local function renderRows()
+
function p.buildtext(params)
    -- Gets the union of the header and data argument numbers,
+
local class = params.class or ''
    -- and renders them all in order using addRow.
+
local style = defaultstyle['boldline']
    local rownums = union(getArgNums('header'), getArgNums('data'))
+
if params.style then
    table.sort(rownums)
+
for i, j in pairs(params.style) do
    for k, num in ipairs(rownums) do
+
style[i] = j
        addRow({
+
end
            header = args['header' .. tostring(num)],
+
end
            label = args['label' .. tostring(num)],
+
local text = getvalue(params.value, params) or getWikidataValue(params) or params.defaultvalue
            data = args['data' .. tostring(num)],
+
if text == '-' then
            datastyle = args.datastyle,
+
return
            class = args['class' .. tostring(num)],
+
end
            rowclass = args['rowclass' .. tostring(num)],
+
if not text then
            rowstyle = args['rowstyle' .. tostring(num)],
+
addmaintenancecat(params.maintenancecat, params.sortkey)
            dataid = args['dataid' .. tostring(num)],
+
return nil
            labelid = args['labelid' .. tostring(num)],
+
end
            headerid = args['headerid' .. tostring(num)],
+
local formattedtext = mw.html.create('p')
            rowid = args['rowid' .. tostring(num)]
+
:addClass(class)
        })
+
:css(style)
    end
+
:wikitext(text)
 +
:done()
 +
return formattedtext
 
end
 
end
  
local function renderNavBar()
+
function p.buildrow(params)
    if not args.name then return end
+
local class = params.class or ''
   
+
local style = params.style or {}
    root
+
local value, number =  getvalue(params.value, params)
        :tag('tr')
+
if not value then
            :tag('td')
+
value, number =  getWikidataValue(params, 'wikidata')
                :attr('colspan', '2')
+
end
                :css('text-align', 'right')
+
if (not value) and (params.property) then
                :wikitext(navbar{
+
value, number = expandquery({property = params.property})  -- the property key takes a string value,  that would not work well using the wikidata key
                    args.name,
+
end
                    mini = 1,
+
if not value then
                })
+
value = params.defaultvalue
 +
end
 +
if value == '-' then
 +
return nil
 +
end
 +
if not number then
 +
number = 0 -- == indéfini
 +
end
 +
if not value then
 +
if params.maintenancecat then
 +
local maintenancecat = getvalue(params.maintenancecat, params)
 +
addmaintenancecat(maintenancecat, params.sortkey)
 +
end
 +
return nil
 +
end
 +
 
 +
local label = params.label
 +
if number > 1 and (params.plurallabel) then
 +
label = params.plurallabel
 +
elseif number == 1 and (params.singularlabel) then
 +
label = params.singularlabel
 +
end
 +
if type(label) == 'function' then
 +
label = label(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 (params.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)
 +
: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
 
end
  
local function renderItalicTitle()
+
function p.buildsuccession(params)
    local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title'])
+
if not params.value then
    if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
+
return nil
        root:wikitext(mw.getCurrentFrame():expandTemplate({title = 'italic title'}))
+
end
    end
+
 +
--local style = params.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 colspan = '2'
 +
cellI = mw.html.create('td')
 +
:attr({colspan = colspan})
 +
:attr({align = 'center'})
 +
 +
local styleT = {}
 +
styleT['background-color'] = 'transparent'
 +
styleT['width'] = '100%'
 +
tabC = mw.html.create('table')
 +
:attr({cellspacing = '0'})
 +
:css(styleT)
 +
 +
local row = mw.html.create('tr')
 +
 
 +
local color = params.color
 +
 
 +
local style = {}
 +
local arrowLeft
 +
local arrowRight
 +
 +
if color == 'default' then
 +
style['background-color'] = '#E6E6E6'
 +
arrowLeft = '[[Fichier:Fleche-defaut-gauche.png|13px|alt=Précédent|link=]]'
 +
arrowRight = '[[Fichier:Fleche-defaut-droite.png|13px|alt=Précédent|link=]]'
 +
else
 +
style['background-color'] = color
 +
arrowLeft = '[[Fichier:Fleche-defaut-gauche-gris-32.png|13px|alt=Suivant|link=]]'
 +
arrowRight = '[[Fichier:Fleche-defaut-droite-gris-32.png|13px|alt=Suivant|link=]]'
 +
end
 +
 +
local styleTrans = {}
 +
styleTrans['background-color'] = '#F9F9F9'
 +
 +
local values = params.value
 +
local before = values['before']
 +
local center = values['center']
 +
local after = values['after']
 +
 +
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
 
end
  
local function renderTrackingCategories()
+
function p.buildrow1col(params)
    if args.decat ~= 'yes' then
+
        if #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
+
if not params.value then
            root:wikitext('[[Category:Articles which use infobox templates with no data rows]]')
+
return nil
        end
+
end
        if args.child == 'yes' and args.title then
+
            root:wikitext('[[Category:Pages which use embedded infobox templates with the title parameter]]')
+
--local style = params.style or {}
        end
+
--style['text-align'] = style['text-align'] or 'center'
    end
+
--style['color'] = style['color'] or '#000000'
 +
--style['background-color'] = style['background-color'] or '#F9F9F9'
 +
 +
local rowcolor
 +
if params.color == 'secondcolor' then
 +
rowcolor = secondcolor
 +
else
 +
rowcolor = params.color
 +
end
 +
 +
local style = {}
 +
style['padding'] = '4px'
 +
style['text-align'] = 'center'
 +
style['background-color'] = rowcolor or '#F9F9F9'
 +
style['color'] = '#000000'
 +
 +
local text = params.value
 +
 
 +
local colspan ='2'
 +
 
 +
local formattedlabel
 +
formattedlabel = mw.html.create('th')
 +
:attr({colspan = colspan})
 +
:css(style)
 +
:wikitext(text)
 +
:done()
 +
 
 +
local row = mw.html.create('tr')
 +
:addClass(class)
 +
:css(style)
 +
:node(formattedlabel)
 +
:done()
 +
 +
return row
 
end
 
end
  
local function _infobox()
+
function p.buildtable(params)
    -- Specify the overall layout of the infobox, with special settings
+
local tab = mw.html.create('table'):css(params.style or {})
    -- if the infobox is used as a 'child' inside another infobox.
 
    if args.child ~= 'yes' then
 
        root = mw.html.create('table')
 
       
 
        root
 
            :addClass('infobox')
 
            :addClass(args.bodyclass)
 
           
 
            if args.subbox == 'yes' then
 
                root
 
                    :css('padding', '0')
 
                    :css('border', 'none')
 
                    :css('margin', '-3px')
 
                    :css('width', 'auto')
 
                    :css('min-width', '100%')
 
                    :css('font-size', '100%')
 
                    :css('clear', 'none')
 
                    :css('float', 'none')
 
                    :css('background-color', 'transparent')
 
            else
 
                root
 
                    :css('width', '22em')
 
            end
 
        root
 
            :cssText(args.bodystyle)
 
   
 
        renderTitle()
 
        renderAboveRow()
 
    else
 
        root = mw.html.create()
 
       
 
        root
 
            :wikitext(args.title)
 
    end
 
  
    renderSubheaders()
+
-- CREATE ROWS
    renderImages()  
+
local rows = {}
    renderRows()  
+
for k, l in pairs(params.rows) do
    renderBelowRow()
+
if type(l) == 'table' and l.type == 'multi' then -- when a single function is used for return several rows
    renderNavBar()
+
table.remove(params.rows, k)
    renderItalicTitle()
+
local count = 0
    renderTrackingCategories()
+
for m, n in pairs(l.rows) do
   
+
table.insert(params.rows, k + count, n)
    return tostring(root)
+
count = count + 1
 +
end
 +
l = params.rows[k]
 +
end
 +
 
 +
if type(l) == 'function' then --accepte les fonctions qui retournent des tables
 +
l = l(localdata, item)
 +
end
 +
if type(l) == 'nil' then
 +
--ne rien faire (quand la valeur est originellemenet une fonctin elle peut retourner nil)
 +
elseif type(l) ~= 'table' then
 +
return error('les lignes d\'infobox ("rows") doivent être des tables, est ' .. type(l))
 +
else
 +
local row = p.buildblock(l)
 +
table.insert(rows, row)
 +
end
 +
end
 +
if #rows == 0 then
 +
return nil
 +
end
 +
 
 +
-- ADD TITLE
 +
local title
 +
if params.title or params.singulartitle or params.pluraltitle then
 +
local text
 +
if #rows > 1 and params.pluraltitle then
 +
text = pluraltitle
 +
elseif #rows == 1 and params.singulartitle then
 +
text = pluraltitle
 +
else
 +
text = params.title
 +
end
 +
 
 +
local style = params.titlestyle or {}
 +
style['text-align'] = style['text-align'] or 'center'
 +
style['color'] = style['color'] or thirdcolor
 +
style['background-color'] = style['background-color'] or maincolor
 +
 
 +
local colspan ='2'
 +
title = mw.html.create('caption')
 +
:attr({colspan = colspan})
 +
: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 params.separator then
 +
local separator = p.separator(params)
 +
tab:node(separator)
 +
end
 +
tab:allDone()
 +
return tab
 +
end
 +
 
 +
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
 
end
  
local function preprocessSingleArg(argName)
+
function p.buildmap(params)-- TODO  : gestion de plusieurs points
    -- If the argument exists and isn't blank, add it to the argument table.
+
 
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
+
-- paramètre d'affichage
    if origArgs[argName] and origArgs[argName] ~= '' then
+
local maplist = getvalue(params.maps)
        args[argName] = origArgs[argName]
+
local pointtype = params.pointtype
    end
+
local maptype = params.maptype -- choisit le type de carte le plus approprié (relief, administratif, etc.)
 +
if type(maplist) == 'function' then
 +
maplist = maplist(localdata, item)
 +
end
 +
local width = tonumber(params.width) or 280
 +
if width > 280 then
 +
addmaintenancecat("Erreur d'Infobox/Image trop grande")
 +
return 'image trop grande, la largeur doit être inférieure ou égale à 280px'
 +
end
 +
 
 +
-- récupération des données locales
 +
local latitude, longitude, globe = params.latitude, params.longitude, params.globe
 +
if type(params.latitude) == 'function' then
 +
latitude, longitude = params.latitude(localdata, item), params.longitude(localdata, item)
 +
else
 +
latitude, longitude = localdata[params.latitude], localdata[params.longitude]
 +
end
 +
 +
-- récupération des données wikidata
 +
if (not latitude or not longitude) and params.wikidata then
 +
local query = params.wikidata
 +
if type(query) == 'function' then
 +
query = query()
 +
end
 +
if not query then
 +
return nil
 +
end
 +
query.excludespecial = true
 +
query.entity = query.entity or item
 +
local claims = wikidata.getClaims(query)
 +
if not claims then
 +
return nil
 +
end
 +
local val = claims[1].mainsnak.datavalue.value
 +
latitude, longitude, globe = val.latitude, val.longitude, val.globe
 +
end
 +
 +
if not latitude or not longitude then
 +
return nil
 +
end
 +
local newparams = {maplist = maplist, pointtype = pointtype, maptype = maptype, width = width, item = item, latitude = latitude, longitude = longitude, globe = globe}
 +
if params.params and type(params.params) == 'table' then -- paramètres additionnels
 +
for i, j in pairs(params.params) do
 +
newparams[i] = j
 +
end
 +
end
 +
return mapmod.multimap(newparams)
 
end
 
end
  
local function preprocessArgs(prefixTable, step)
+
function p.buildfooter(params)
    -- Assign the parameters with the given prefixes to the args table, in order, in batches
+
if not params then
    -- of the step size specified. This is to prevent references etc. from appearing in the
+
params = {}
    -- wrong order. The prefixTable should be an array containing tables, each of which has
+
end
    -- two possible fields, a "prefix" string and a "depend" table. The function always parses
+
    -- parameters containing the "prefix" string, but only parses parameters in the "depend"
+
local class = 'navbar noprint ' .. (params.class or '')
    -- table if the prefix parameter is present and non-blank.
+
local style = params.style or {}
    if type(prefixTable) ~= 'table' then
+
style['border-top'] = style['border-top'] or '1px solid ' .. maincolor
        error("Non-table value detected for the prefix table", 2)
+
    end
+
local backlinkstr = '[' .. tostring( mw.uri.fullUrl( page.name, '&veaction=edit&section=0' ) ) .. ' ' .. i18n['edit'] .. ']'
    if type(step) ~= 'number' then
+
.. ' - [' .. tostring( mw.uri.fullUrl( page.name, '&action=edit&section=0' ) ) .. ' ' .. i18n['edit code'] .. ']'
        error("Invalid step value detected", 2)
 
    end
 
   
 
    -- Get arguments without a number suffix, and check for bad input.
 
    for i,v in ipairs(prefixTable) do
 
        if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
 
            error('Invalid input detected to preprocessArgs prefix table', 2)
 
        end
 
        preprocessSingleArg(v.prefix)
 
        -- Only parse the depend parameter if the prefix parameter is present and not blank.
 
        if args[v.prefix] and v.depend then
 
            for j, dependValue in ipairs(v.depend) do
 
                if type(dependValue) ~= 'string' then
 
                    error('Invalid "depend" parameter value detected in preprocessArgs')
 
                end
 
                preprocessSingleArg(dependValue)
 
            end
 
        end
 
    end
 
  
    -- Get arguments with number suffixes.
+
local itemlinkstr
    local a = 1 -- Counter variable.
+
if item then
    local moreArgumentsExist = true
+
itemlinkstr = '[[d:' .. item.id .. '|' .. i18n['edit item'] .. ']]'
    while moreArgumentsExist == true do
+
end
        moreArgumentsExist = false
+
local editstr = backlinkstr
        for i = a, a + step - 1 do
+
if itemlinkstr then
            for j,v in ipairs(prefixTable) do
+
editstr = editstr .. ' - ' .. itemlinkstr
                local prefixArgName = v.prefix .. tostring(i)
+
end
                if origArgs[prefixArgName] then
+
local editlinkspan = mw.html.create('span')
                    moreArgumentsExist = true -- Do another loop if any arguments are found, even blank ones.
+
:css({['text-align'] = "left"})
                    preprocessSingleArg(prefixArgName)
+
:addClass('plainlinks')
                end
+
:wikitext(editstr)
                -- Process the depend table if the prefix argument is present and not blank, or
+
:done()
                -- we are processing "prefix1" and "prefix" is present and not blank, and
+
local doclinkstr = '[[Image:Info Simple.svg|12px|link=' .. localdata.templatename .. '|' .. i18n['see doc'] .. ']]'
                -- if the depend table is present.
+
-- si ce lien ne marche pas toujours, il faut ajouter un variable pour le nom de l'infobox récupéré par le frame
                if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
+
local doclinkspan = mw.html.create('span')
                    for j,dependValue in ipairs(v.depend) do
+
:css({['text-align'] = "right"})
                        local dependArgName = dependValue .. tostring(i)
+
:wikitext(doclinkstr)
                        preprocessSingleArg(dependArgName)
+
:done()
                    end
+
                end
+
local footer = mw.html.create('p')
            end
+
:addClass(class)
        end
+
:css(style)
        a = a + step
+
:node(editlinkspan)
    end
+
:node(doclinkspan)
 +
return footer
 
end
 
end
+
 
function p.infobox(frame)
+
function p.buildblock(block)
    -- If called via #invoke, use the args passed into the invoking template.
+
if type(block) == 'function' then
    -- Otherwise, for testing purposes, assume args are being passed directly in.
+
block = block()
    if frame == mw.getCurrentFrame() then
+
end
        origArgs = frame:getParent().args
+
 
    else
+
local blocktypes = { -- list of functions for block buildings
        origArgs = frame
+
['invalid'] = p.buildinvalidblock,
    end
+
['external text'] = p.buildexternaltext,
   
+
['footer'] = p.buildfooter,
    -- Parse the data parameters in the same order that the old {{infobox}} did, so that
+
['images'] = p.buildimages,
    -- references etc. will display in the expected places. Parameters that depend on
+
['map']= p.buildmap,
    -- another parameter are only processed if that parameter is present, to avoid
+
['mixed'] = p.buildrow,
    -- phantom references appearing in article reference lists.
+
['navbox'] = p.buildnavbox,
    preprocessSingleArg('child')
+
['table'] = p.buildtable,
    preprocessSingleArg('bodyclass')
+
['row'] = p.buildrow,
    preprocessSingleArg('subbox')
+
['row1col'] = p.buildrow1col,
    preprocessSingleArg('bodystyle')
+
['succession'] = p.buildnavbox,
    preprocessSingleArg('title')
+
['text'] = p.buildtext,
    preprocessSingleArg('titleclass')
+
['title'] = p.buildtitle,
    preprocessSingleArg('titlestyle')
+
}
    preprocessSingleArg('above')
+
if type(block) ~= 'table' or (not block.type) or (not blocktypes[block.type]) then
    preprocessSingleArg('aboveclass')
+
return blocktypes['invalid'](block)
    preprocessSingleArg('abovestyle')
+
end
    preprocessArgs({
+
return blocktypes[block.type](block)  
        {prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}}
 
    }, 10)
 
    preprocessSingleArg('subheaderstyle')
 
    preprocessSingleArg('subheaderclass')
 
    preprocessArgs({
 
        {prefix = 'image', depend = {'caption', 'imagerowclass'}}
 
    }, 10)
 
    preprocessSingleArg('captionstyle')
 
    preprocessSingleArg('imagestyle')
 
    preprocessSingleArg('imageclass')
 
    preprocessArgs({
 
        {prefix = 'header'},
 
        {prefix = 'data', depend = {'label'}},
 
        {prefix = 'rowclass'},
 
        {prefix = 'rowstyle'},
 
        {prefix = 'class'},
 
        {prefix = 'dataid'},
 
        {prefix = 'labelid'},
 
        {prefix = 'headerid'},
 
        {prefix = 'rowid'}
 
    }, 50)
 
    preprocessSingleArg('headerclass')
 
    preprocessSingleArg('headerstyle')
 
    preprocessSingleArg('labelstyle')
 
    preprocessSingleArg('datastyle')
 
    preprocessSingleArg('below')
 
    preprocessSingleArg('belowclass')
 
    preprocessSingleArg('belowstyle')
 
    preprocessSingleArg('name')
 
    args['italic title'] = origArgs['italic title'] -- different behaviour if blank or absent
 
    preprocessSingleArg('decat')
 
 
    return _infobox()
 
 
end
 
end
   
+
 
 +
function p._build(modulename, params, templatename)
 +
 
 +
-- fill-up global variable localdata using params
 +
for i, j in pairs(params) do
 +
if j and mw.text.trim(j) ~= '' then -- empty parameters are ignored
 +
localdata[i] = j
 +
end
 +
end
 +
localdata.templatename = templatename or modulename
 +
 
 +
-- load wikidata item as a global variable:
 +
if localdata.wikidata == '-' then
 +
item = nil
 +
else
 +
item = wikidata.getEntity(localdata.wikidata)
 +
end
 +
 +
-- assign rank to the infobox, "secondary" means special formatting like no displaytitle for coordinates
 +
local infoboxrank = 'main' -- main infobox of the page, with coordinates displayed in title etc.
 +
if page.namespace ~= 0 then
 +
infoboxrank = 'secondary'
 +
end
 +
-- if infobox is linked to another item: rank = secondary
 +
if item then
 +
local itemlink = mw.wikibase.sitelink(item.id)
 +
local pagetitle = mw.title.getCurrentTitle().text
 +
if (itemlink or '') ~= pagetitle then
 +
infoboxrank = 'secondary'
 +
end
 +
end
 +
localdata.infoboxrank = infoboxrank
 +
 
 +
-- load infobox module page
 +
moduledata = require('Module:Infobox/' .. modulename)
 +
moduledata.name = modulename
 +
-- defines main color
 +
maincolor = localdata['couleur infobox'] or localdata['couleur boîte'] or moduledata.maincolor or maincolor
 +
secondcolor = moduledata.secondcolor or secondcolor
 +
thirdcolor =  moduledata.thirdcolor or thirdcolor
 +
if maincolor:match( '^%x%x%x%x%x%x$' ) or maincolor:match( '^%x%x%x$' ) then
 +
maincolor = '#' .. maincolor
 +
end
 +
 +
-- class
 +
local class = 'infobox_v3'
 +
if moduledata.class then
 +
class = class .. ' ' .. moduledata.class
 +
end
 +
 +
-- style
 +
local style = moduledata.style or {}
 +
if not style['max-width'] then
 +
style['max-width'] = '300px'
 +
end
 +
 +
-- build infobox
 +
infobox :addClass(class)
 +
:css(style)
 +
for i, j in pairs( moduledata.parts ) do
 +
infobox:node( p.buildblock(j) )
 +
end
 +
infobox :node(p.buildfooter(moduledata.footer))
 +
:done()
 +
 
 +
return tostring(infobox) .. externaltext, maintenance
 +
end
 +
 
 +
function p.build(frame)
 +
local name =  frame.args.nom
 +
local parent = frame:getParent()
 +
local templatename = parent:getTitle() -- au cas où il soit différent du nom du module
 +
local params = parent.args
 +
return p._build(name, params, templatename)
 +
end
 +
 
 
return p
 
return p

Version du 12 mars 2016 à 11:49

La documentation pour ce module peut être créée à Module:Infobox/doc

local p = {}
local lang = 'fr'
-- variables globales alimentées par les paramètres utilisés
item = nil -- l'élément Wikidata lié
moduledata = nil -- la sous-page de module:Infobox demandéep
localdata = {}-- données concernant les paramètres passés au modèle
page = { -- données concernant la page où est affichée l'infobox
	name = mw.title.getCurrentTitle().prefixedText,
	namespace =  mw.title.getCurrentTitle().namespace
}
local maincolor, secondcolor, thirdcolor = '#E1E1E1', '#E1E1E1', '#000000'

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

-- objes secondaires à retourner
local maintenance = '' -- chaîne retournfoée avec le module : cats de maintenance
local externaltext = '' -- par exemple coordonnées en titre
-- modules importés
local wikidata = require('Module:Interface Wikidata').fromLua
local wd = require 'Module:Wikidata'
local defaultstyle = require "Module:Infobox/Style"
local mapmod = require "Module:Carte"

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",
}

local function addwikidatacat(prop)
	maintenance = maintenance .. wikidata.addtrackingcat(prop)
end

local function expandquery(query)
	local value, number -- valeur à retourner, nombre de valeurs pour accorder le libellé
	if not query.entity then
		query.entity = item
	end
	if not query.conjtype then
		query.conjtype = 'comma'
	end
	local claims = wikidata.getClaims(query)
		if (not claims) then
		return nil
	end
	return wikidata.formatAndCat(query), #claims -- pour l'accord au pluriel
end

local function getWikidataValue(params, wikidataparam)
	-- Récupère la valeur Wikidata pour la valeur, soit dans le paramètre "wikidata" soit dans le praramètre "property"
	if not item then
		return nil
	end
	local value, number
	
	if not wikidataparam then -- par défaut la valeur wikidata est dans le paramètre "wikidata" mais dans les structures composées comme "title", il y a plusieurs paramètres wikidata
		wikidataparam = 'wikidata'
	end

	if params[wikidataparam] then
		if type(params[wikidataparam]) == 'function' then
			return params[wikidataparam](item)
		elseif type(params[wikidataparam]) == 'table' then
			return expandquery(params[wikidataparam])
		else
			return params[wikidataparam]
		end
	end
end

local function getvalue(val, params)
	if type(val) == 'string' then
		return localdata[val]
	elseif type(val) == 'function' then
		return val(localdata, item, params)
	elseif type(val) == 'table' then
		for i, j in pairs(val) do -- si plusieurs paramètres possibles (legacy de vieux code), prendre le preimeir non bide
			if localdata[j] then
				return localdata[j]
			end
		end
	end
end

local function addmaintenancecat(cat, sortkey)
	if page.namespace ~= 0 then
		return ''
	end
	if cat then
		maintenance = maintenance .. '[[Category:' .. cat .. '|' .. (sortkey or page.name) .. ']]'
	end
end

function p.separator(params)
	local style = params['separator style'] or {}
	style.height = style.height or '2px'
	style['background-color'] = style['background-color'] or maincolor
	
	return mw.html.create('hr'):css( style )	
end

function p.buildtitle(params)
	local text = getvalue(params.value, params) or params.textdefaultvalue or  getWikidataValue(params) or mw.title.getCurrentTitle().text
	local subtext = getvalue(params.subtitle) or  getWikidataValue(params, 'wikidatasubtitle') or params.subtitledefaultvalue
	if subtext and (subtext ~= text) then
		text = text .. '<br /><small>' .. subtext .. '</small>'
	end
	local icon = params.icon or ''
	if icon ~= '' and not params.large then
		icon = 'icon ' .. icon
	end
	local class = 'entete ' .. icon
	
	-- overwrites with those provided in the module
	local style = {}
	style['background-color'] = maincolor
	style['color'] = thirdcolor
	if params.style then
		for i, j in pairs(params.style) do
			style[i] = j
		end
	end
	local title = mw.html.create('div')
		:addClass(class)
		:css(style)
		:tag('div')
			:wikitext(text)
		:allDone()
	return title
end

function p.buildnavbox(params)
	
	-- définition du style
	local class = "overflow nav " .. (params.class or '')
	local style = params.style or {}

	if params.separated then -- options pour ajouter une ligne de séparation au dessus
		style['border-top'] = '1px solid' .. maincolor
	end

	-- ajustement des paramètres de données
	params.previousval = params.previousval or params.previousparameter -- nom de paramètre obsolète
	params.nextval = params.nextval or params.nextparameter
	
	if params.previousproperty then
		params.previouswikidata = {property = params.previousproperty}
	end
	if params.nextproperty then
		params.nextwikidata = {property = params.nextproperty}
	end
	

	local previousval = getvalue(params.previousval, params) or getWikidataValue(params, 'previouswikidata')
	local nextval = getvalue(params.nextval, params) or getWikidataValue(params, 'nextwikidata')
	
	local navbox
	if params.inner then -- pour celles qui sont à l'intérieur d'une table
		navbox = mw.html.create('tr'):tag('th'):attr('colspan', 2)
		style['font-weight'] = style['font-weight'] or 'normal'
	else
		navbox = mw.html.create('div')
	end
	
	navbox
		:addClass(class)
		:css(style)
		:tag('div')
			:addClass('prev_bloc')
			:wikitext(previousval)
			:done()
		:tag('div')
			:addClass('next_bloc')
			:wikitext(nextval)
			:done()
		:allDone()
	return navbox
end

function p.buildimages(params)
	local images = {}
	local upright, link, caption, size -- size is deprecated
	if type(params.imageparameters) == 'string' then
		params.imageparameters = {params.imageparameters}
	end
	if not params.imageparameters then -- s'il n'y a pa de paramètre image, continuer, peut-être y-a-t-il une image par défaut définie dans le module d'infobox
		params.imageparameters = {}
	end
	for j, k in ipairs(params.imageparameters) do
		table.insert(images, localdata[k])
	end
	
	-- Images de Wikidata
	if #images == 0 and item then
		if params.property then
			images = wikidata.getClaims{entity = item, property = params.property} or {}
			if #images > 0 then
				addwikidatacat(params.property)
			end
		end
		if params.wikidata then
			images = params.wikidata()
			if type(images) == 'string' then
				return images
			end -- c'est probablement une erreur dans la requête => afficher le message
		end
	end
	if type(images[1]) == 'table' then
		for i, j in pairs(images) do
			if j.mainsnak.snaktype ~= 'value' then
				return
			end
			local wdcaptions, wdcaption
			local q = images[i].qualifiers
			if q then
				wdcaptions = q['P2096']
			end
			if wdcaptions then
				for k, l in pairs(wdcaptions) do
					if l.datavalue.value and l.datavalue.value.language == lang then
						wdcaption = wd.formatSnak(l)
					end
				end
			end
			if wdcaption and caption then -- si deux légendes, désactivées pour éviter les conflits
				caption = nil
			elseif wdcaption then
				caption = wdcaption
			end
			if i > (params.numval) then
				images[i] = nil
			else
				images[i] = j.mainsnak.datavalue.value
			end
		end
	end

	-- Images par défaut
	local isdefault = false
	if #images == 0 then
		if params.maintenancecat then
			local maintenancecat = getvalue(params.maintenancecat, params)
			if maintenancecat and maintenancecat ~= '-' then
				addmaintenancecat(maintenancecat, params.sortkey)
			end
		end
		if params.defaultimages then
			images = params.defaultimages
			if type(images) == 'string' then
				images = {images}
			end
		end
		upright, caption, link = params.defaultimageupright, params.defaultimagecaption, params.defaultimagelink
	end
	if #images == 0 then
		return nil
	end
	
	upright = size or getvalue(params.uprightparameter) or params.defaultupright or "1.2"
	link = link or getvalue(params.linkparameter) or params.defaultlink
	caption = caption or getvalue(params.captionparameter) or params.defaultcaption or ''

	if type(size) == 'function' then
		size = size(localdata)
	end
	if type(link) == 'function' then
		link = link()
	end
	if type(caption) == 'function' then
		caption = caption(localdata)
	end

	-- taille avec "size" (obsolète)
	size = size or getvalue(params.sizeparameter) or params.defaultsize -- deprecated
	if size then
		local numsize = size:gsub('px', '')
		numsize = mw.ustring.gsub(numsize, 'x.*', '')
		numsize = tonumber(numsize)
		if type(numsize) ~= 'number' or numsize > 280 then
			addmaintenancecat("taille d'image invalide")
		end
		if tonumber(size) then
			size = size .. 'px'
		end
		size = '|' .. size
	else
		size = ''
	end
	
	if link then
		link = '|link=' .. link
	else
		link = ''
	end
	local style = params.style or {padding ='2px 0',}

	-- Partie image

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

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

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

function p.buildtext(params)
	local class = params.class or ''
	local style = defaultstyle['boldline']
	if params.style then
		for i, j in pairs(params.style) do
			style[i] = j
		end
	end
	local text = getvalue(params.value, params) or getWikidataValue(params) or params.defaultvalue
	if text == '-' then
		return
	end
	if not text then
		addmaintenancecat(params.maintenancecat, params.sortkey)
		return nil
	end
	local formattedtext = mw.html.create('p')
		:addClass(class)
		:css(style)
		:wikitext(text)
		:done()
	return formattedtext
end

function p.buildrow(params)
	local class = params.class or ''
	local style = params.style or {}
	local value, number =  getvalue(params.value, params)
	if not value then
		value, number =  getWikidataValue(params, 'wikidata')
	end
	if (not value) and (params.property) then
		value, number = expandquery({property = params.property})  -- the property key takes a string value,  that would not work well using the wikidata key 
	end
	if not value then
		value = params.defaultvalue
	end
	if value == '-' then
		return nil
	end
	if not number then
		number = 0 -- == indéfini
	end
	if not value then
		if params.maintenancecat then
			local maintenancecat = getvalue(params.maintenancecat, params)
			addmaintenancecat(maintenancecat, params.sortkey)
		end
		return nil
	end

	local label = params.label
	if number > 1 and (params.plurallabel) then
		label = params.plurallabel
	elseif number == 1 and (params.singularlabel) then
		label = params.singularlabel
	end
	if type(label) == 'function' then
			label = label(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 (params.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)
			: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

function p.buildsuccession(params)
if not params.value then
		return nil
	end
		
	--local style = params.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 colspan = '2'
	cellI = mw.html.create('td')
			:attr({colspan = colspan})
			:attr({align = 'center'})
	
	local styleT = {}
	styleT['background-color'] = 'transparent'
	styleT['width'] = '100%'
	tabC = mw.html.create('table')
			:attr({cellspacing = '0'})
			:css(styleT)
	
	local row = mw.html.create('tr')

	local color = params.color

	local style = {}
	local arrowLeft
	local arrowRight
	
	if color == 'default' then
		style['background-color'] = '#E6E6E6'
		arrowLeft = '[[Fichier:Fleche-defaut-gauche.png|13px|alt=Précédent|link=]]'
		arrowRight = '[[Fichier:Fleche-defaut-droite.png|13px|alt=Précédent|link=]]'
	else
		style['background-color'] = color
		arrowLeft = '[[Fichier:Fleche-defaut-gauche-gris-32.png|13px|alt=Suivant|link=]]'
		arrowRight = '[[Fichier:Fleche-defaut-droite-gris-32.png|13px|alt=Suivant|link=]]'
	end
	
	local styleTrans = {}
	styleTrans['background-color'] = '#F9F9F9'
	
	local values = params.value
	local before = values['before']
	local center = values['center']
	local after = values['after']
	
	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

function p.buildrow1col(params)
	
	if not params.value then
		return nil
	end
		
	--local style = params.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 rowcolor
	if params.color == 'secondcolor' then
		rowcolor = secondcolor
	else
		rowcolor = params.color
	end
	
	local style = {}
	style['padding'] = '4px'
	style['text-align'] = 'center'
	style['background-color'] = rowcolor or '#F9F9F9'
	style['color'] = '#000000'
	
	local text = params.value

	local colspan ='2'

	local formattedlabel
	formattedlabel = mw.html.create('th')
		:attr({colspan = colspan})
		:css(style)
		:wikitext(text)
		:done()

	local row = mw.html.create('tr')
		:addClass(class)
		:css(style)
		:node(formattedlabel)
		:done()
	
	return row
end

function p.buildtable(params)
	local tab = mw.html.create('table'):css(params.style or {})

	-- CREATE ROWS
	local rows = {}
		for k, l in pairs(params.rows) do
		if type(l) == 'table' and l.type == 'multi' then -- when a single function is used for return several rows
			table.remove(params.rows, k)
			local count = 0
			for m, n in pairs(l.rows) do
				table.insert(params.rows, k + count, n)
				count = count + 1
			end
			l = params.rows[k]
		end

		if type(l) == 'function' then --accepte les fonctions qui retournent des tables
			l = l(localdata, item)
		end
		if type(l) == 'nil' then
			--ne rien faire (quand la valeur est originellemenet une fonctin elle peut retourner nil)
		elseif type(l) ~= 'table' then
			return error('les lignes d\'infobox ("rows") doivent être des tables, est ' .. type(l))
		else
			local row = p.buildblock(l)
			table.insert(rows, row)
		end
	end
	if #rows == 0 then
		return nil
	end

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

		local style = params.titlestyle or {}
		style['text-align'] = style['text-align'] or 'center'
		style['color'] = style['color'] or thirdcolor
		style['background-color'] = style['background-color'] or maincolor

		local colspan ='2'
		title = mw.html.create('caption')
			:attr({colspan = colspan})
			: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 params.separator then
		local separator = p.separator(params)
		tab:node(separator)
	end
	tab:allDone()
	return tab
end

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

function p.buildmap(params)-- TODO  : gestion de plusieurs points

	-- paramètre d'affichage 
	local maplist = getvalue(params.maps)
	local pointtype = params.pointtype
	local maptype = params.maptype -- choisit le type de carte le plus approprié (relief, administratif, etc.)	
	if type(maplist) == 'function' then
		maplist = maplist(localdata, item)
	end
	local width = tonumber(params.width) or 280
	if width > 280 then
		addmaintenancecat("Erreur d'Infobox/Image trop grande")
		return 'image trop grande, la largeur doit être inférieure ou égale à 280px'
	end

	-- récupération des données locales
	local latitude, longitude, globe = params.latitude, params.longitude, params.globe
	if type(params.latitude) == 'function' then
		latitude, longitude = params.latitude(localdata, item), params.longitude(localdata, item)
	else
		latitude, longitude = localdata[params.latitude], localdata[params.longitude]
	end
	
	-- récupération des données wikidata
	if (not latitude or not longitude) and params.wikidata then
		local query = params.wikidata
		if type(query) == 'function' then
			query = query()
		end
		if not query then
			return nil
		end
		query.excludespecial = true
		query.entity = query.entity or item
		local claims = wikidata.getClaims(query)
		if not claims then
			return nil
		end
		local val = claims[1].mainsnak.datavalue.value
		latitude, longitude, globe = val.latitude, val.longitude, val.globe
	end
	
	if not latitude or not longitude then
		return nil
	end
	local newparams = {maplist = maplist, pointtype = pointtype, maptype = maptype, width = width, item = item, latitude = latitude, longitude = longitude, globe = globe}
	if params.params and type(params.params) == 'table' then -- paramètres additionnels
		for i, j in pairs(params.params) do
			newparams[i] = j
		end
	end
	return mapmod.multimap(newparams)
end

function p.buildfooter(params)
	if not params then
		params = {}
	end
	
	local class = 'navbar noprint ' .. (params.class or '')
	local style = params.style or {}
	style['border-top'] = style['border-top'] or '1px solid ' .. maincolor
	
	local backlinkstr = '[' .. tostring( mw.uri.fullUrl( page.name, '&veaction=edit&section=0' ) ) .. ' ' .. i18n['edit'] .. ']'
		.. ' - [' .. tostring( mw.uri.fullUrl( page.name, '&action=edit&section=0' ) ) .. ' ' .. i18n['edit code'] .. ']'

	local itemlinkstr
	if item then
		itemlinkstr = '[[d:' .. item.id .. '|' .. i18n['edit item'] .. ']]'
	end
	local editstr = backlinkstr
	if itemlinkstr then
		editstr = editstr .. ' - ' .. itemlinkstr
	end
	local editlinkspan =  mw.html.create('span')
		:css({['text-align'] = "left"})
		:addClass('plainlinks')
		:wikitext(editstr)
		:done()
	local doclinkstr = '[[Image:Info Simple.svg|12px|link=' .. localdata.templatename .. '|' .. i18n['see doc'] .. ']]'
	-- si ce lien ne marche pas toujours, il faut ajouter un variable pour le nom de l'infobox récupéré par le frame
	local doclinkspan = mw.html.create('span')
		:css({['text-align'] = "right"})
		:wikitext(doclinkstr)
		:done()
	
	local footer = mw.html.create('p')
		:addClass(class)
		:css(style)
		:node(editlinkspan)
		:node(doclinkspan)
	return footer
end

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

	local blocktypes = { -- list of functions for block buildings
		['invalid'] = p.buildinvalidblock,
		['external text'] = p.buildexternaltext,
		['footer'] = p.buildfooter,
		['images'] = p.buildimages,
		['map']= p.buildmap,
		['mixed'] = p.buildrow,
		['navbox'] = p.buildnavbox,
		['table'] = p.buildtable,
		['row'] = p.buildrow,
		['row1col'] = p.buildrow1col,
		['succession'] = p.buildnavbox,
		['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

function p._build(modulename, params, templatename)

	-- fill-up global variable localdata using params
	for i, j in pairs(params) do
		if j and mw.text.trim(j) ~= '' then -- empty parameters are ignored
			localdata[i] = j
		end
	end
	localdata.templatename = templatename or modulename

	-- load wikidata item as a global variable:
	if localdata.wikidata == '-' then
		item = nil
	else
		item = wikidata.getEntity(localdata.wikidata)
	end
	
	-- assign rank to the infobox, "secondary" means special formatting like no displaytitle for coordinates
	local infoboxrank = 'main' -- main infobox of the page, with coordinates displayed in title etc.
	if page.namespace ~= 0 then
		infoboxrank = 'secondary'
	end
	-- if infobox is linked to another item: rank = secondary
	if item then
		local itemlink = mw.wikibase.sitelink(item.id)
		local pagetitle = mw.title.getCurrentTitle().text
		if (itemlink or '') ~= pagetitle then
			infoboxrank = 'secondary'
		end
	end
	localdata.infoboxrank = infoboxrank

	-- load infobox module page
	moduledata = require('Module:Infobox/' .. modulename)
	moduledata.name = modulename
	-- defines main color
	maincolor = localdata['couleur infobox'] or localdata['couleur boîte'] or moduledata.maincolor or maincolor
	secondcolor =  moduledata.secondcolor or secondcolor
	thirdcolor =  moduledata.thirdcolor or thirdcolor
	if maincolor:match( '^%x%x%x%x%x%x$' ) or maincolor:match( '^%x%x%x$' ) then
		maincolor = '#' .. maincolor
	end
	
	-- class
	local class = 'infobox_v3'
	if moduledata.class then
		class = class .. ' ' .. moduledata.class
	end
	
	-- style
	local style = moduledata.style or {}
	if not style['max-width'] then
		style['max-width'] = '300px'
	end
	
	-- build infobox
	infobox	:addClass(class)
			:css(style)
	for i, j in pairs( moduledata.parts ) do
		infobox:node( p.buildblock(j) )
	end
	infobox	:node(p.buildfooter(moduledata.footer))
			:done()

	return tostring(infobox) .. externaltext, maintenance
end

function p.build(frame)
	local name =  frame.args.nom
	local parent = frame:getParent()
	local templatename = parent:getTitle() -- au cas où il soit différent du nom du module
	local params = parent.args
	return p._build(name, params, templatename) 
end

return p