Módulo:Infobox/Testes

Origem: Wikipédia, a enciclopédia livre.
Documentação do módulo[ver] [editar] [histórico] [purgar]

Descrição[editar código-fonte]

Este módulo implementa a predefinição {{Info/Biografia/Lua}}. Por favor consulte a predefinição para mais instruções.

Uso[editar código-fonte]

Subpáginas[editar código-fonte]

Os sub-modelos que começam com um carácter minúsculo são meta-modelos, enquanto os modelos que começam com caracteres maiúsculos devem ser utilizados directamente. Observe que esta lista também inclui arquivos de modelos diversos

Ver também[editar código-fonte]

Outra documentação:

local p = {}
local wikiLang = 'pt'
local localdata = {}-- guarda parâmetros passados à predefinição
local args = {}

-- parâmetros da página mostrados na infocaixa
local page = mw.title.getCurrentTitle()

local maincolor, secondcolor, thirdcolor = '#E1E1E1', '#E1E1E1', '#000000'
-- o objeto principal a mostrar
local infobox = mw.html.create('div')

-- objetos secundários a mostrar
local maintenance = '' -- cadeia devolvida com o módulo : cats de monitoramento
local externaltext = '' -- para exemplo com coordenadas no título
-- modules importados
local wd = require 'Module:Infobox/Wikidata/Testes'
local yesno = require 'Module:Yesno'
local valueexpl = wd.translate("activate-query")
local CategorizacaoABeAD = require('Módulo:Categorização AD e AB de outras wikis')

--[=[
Loads the templatestyles for the infobox.

TODO: FINISH loading base templatestyles here rather than in
MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).
When we do this we should clean up the inline CSS below too.
Will have to do some bizarre conversion category like with sidebar.

]=]
local function loadTemplateStyles()
    local frame = mw.getCurrentFrame()

    -- See function description
    local base_templatestyles = frame:extensionTag{
        name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' }
    }

    local templatestyles = ''
    if args['templatestyles'] then templatestyles = frame:extensionTag{
            name = 'templatestyles', args = { src = args['templatestyles'] }
        }
    end


    return table.concat({
        base_templatestyles, -- see function description
        templatestyles
    })
end

-- maintenance des images dupliquées
local usedImages = {}

local i18n = {
        ['see doc'] = 'Documentação da predefinição',
        ['edit'] = 'editar',
        ['edit code'] = 'editar código-fonte',
        ['edit item'] = 'editar Wikidata',
        ['tracking cat'] = "!Páginas que utilizam dados no Wikidata",
        ['invalid block type'] = "Bloco de dados inválidos dentro do módulo infobox",
        ['default cat'] = "!Monitoramento das infobox",

}
local function expandQuery(query)
    if not query.entity then
        query.entity = localdata.item
    end
    if not query.conjtype then
        query.conjtype = 'new line'
    end
    local claims = wd.getClaims(query)
    if (not claims) then
        return nil
    end

    return wd.formatAndCat(query), wd.getgendernum(claims) -- valor e código que indica o género para acordo do plural do rótulo
end

local function getWikidataValue(params, wikidataparam)
    -- Mostra o valor Wikidata para o valor, quer no parâmetro "wikidata" ou no parâmetro "property"
    if not localdata.item then
        return nil
    end

    if params.blockers then -- bloqueadores são parâmetros locais que desativam a consulta wikidata
        local blockers = params.blockers
        if (type(blockers) == 'string') then
            blockers = {blockers}
        end
        for i, blocker in ipairs(blockers) do
            if localdata[blocker] then
                return nil
            end
        end
    end

    local v, valgendernum -- o valor a devolver e o tipo / número de valores (para a concordância gramatical)

    if not wikidataparam then -- por padrão, o valor wikidata está no parâmetro "wikidata", mas em estruturas compostas como "title", existem vários parâmetros wikidata
        wikidataparam = 'wikidata'
    end

    if params.property and not params[wikidataparam] then params[wikidataparam] = {property = params.property} end

    if params[wikidataparam] then
        if type(params[wikidataparam]) == 'function' then
            v, valgendernum = params[wikidataparam](localdata.item)
        elseif type(params[wikidataparam]) == 'table' then
            v, valgendernum = expandQuery(params[wikidataparam])
        else
            v, valgendernum = params[wikidataparam]
        end
    end
    if not v then
        return nil
    end

    if(type(valgendernum) == 'number') then
        if(valgendernum > 1) then
            valgendernum = 'p'
        else
            valgendernum = 's'
        end
    end

    return v, valgendernum
end

local function getValue(val, params)
    if type(val) == 'string' then
        return localdata[val]
    elseif type(val) == 'function' then
        return val(localdata, localdata.item, params)
    elseif type(val) == 'table' then
        for i, j in pairs(val) do -- se vários parâmetros possíveis (legado de código antigo), pegue o primeiro não vazio
            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 .. '[[Categoria:' .. cat .. '|' .. (sortkey or page.prefixedText) .. ']]'
    end
end

function p.separator(params)
    local style = params['estilo separador'] or params['separador estilo'] or {}
    style.height = style.height or stlyle.altura or '2px'
    style['background-color'] = style['background-color'] or style['cor fundo']or maincolor

    return mw.html.create('hr'):css( style )
end

--[=[
Construir o código do bloco do título da infocaixa

Paramâmetro (lista parcial) :
- value : Maneira de obter o título via getValue (nome ou função do parâmetro do modelo).
- textdefaultvalue : Valor por padrão do título.
- icon : Pictograma da infocaixa.
- italic : Indica se o título deve ser apresentado em itálico.
  Sim italic=true, o parâmetro "título em itálico" da infobox pode forçar a desativação.
- setdisplaytitle : Indica se o título do artigo deve ser formatado como o da infobox.
  Sim setdisplaytitle=true, o parâmetro" título do artigo em itálico " da infobox pode forçar a desativação.
]=]
function p.buildtitle(params)
    local text = getValue(params.value, params) or params.textdefaultvalue or getWikidataValue(params) or page.prefixedText
    local lang = localdata['língua do título'] or ''
    if lang ~= '' then
        local langueFunction = require( 'Module:Língua' ).lingua
        text = langueFunction( { lang, text } )
    end
    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 icon ~= 'defaut' then
        text = text .. mw.getCurrentFrame():extensionTag('templatestyles', '', {src = 'Infobox/Pictograma/' .. mw.text.trim(icon) .. '.css'})
        if not params.large then
            icon = 'icon ' .. icon
        end
    end
    local classes = 'topo ' .. icon

    local italic = params.italic and yesno(localdata['título em itálico'] or '', true, true)
    if italic then
        classes = classes .. ' italic'
    end
    if params.setdisplaytitle and yesno(localdata['itálico'] or '', true, true) then
        local formatTitleModule = require( 'Module:Título em itálico' )
        text = text .. formatTitleModule.setDisplayTitle{ args = {
            lang = lang,
            italic = italic,
            options = 'noreplace',
        } }
    end

    -- 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(classes)
        :css(style)
        :tag('div')
            :wikitext(text)
        :allDone()
    return title
end
p.buildTitle = p.buildtitle

function p.buildnavigator(params)

    -- definição do estilo
    local classes = "navbox " .. (params.class or '')
    local style = params.style or {}

    if params.separated then -- opções para adicionar uma linha de separação acima
        classes = classes .. ' bordered'
        style['border-top'] = '1px solid' .. maincolor
    end

        -- ajuste de parâmetros de dados
    params.previousval = params.previousval or params.previousparameter -- nome do parâmetro obsoleto
    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')

    if previousval  == '-' then previousval  = nil end
    if nextval  == '-' then nextval  = nil end

    local navigator
    if params.inner then -- para aqueles que estão dentro de uma tabela
        navigator = mw.html.create('tr'):tag('th'):attr('colspan', 2)
        style['font-weight'] = style['font-weight'] or 'normal'
    else
        navigator = mw.html.create('div')
    end

    if previousval or nextval then
        navigator
            :addClass(classes)
            :css(style)
            :tag('div')
                :addClass('prev_bloc')
                :wikitext(previousval)
                :done()
            :tag('div')
                :addClass('next_bloc')
                :wikitext(nextval)
                :done()
            :allDone()
        return navigator
    end
    return nil
end
p.buildNavigator = p.buildnavigator

function p.buildimages(params)
    local images = {}
    local upright, link, caption, alt, size  -- size is deprecated
    if type(params.imageparameters) == 'string' then
        params.imageparameters = {params.imageparameters}
    end
    if not params.imageparameters then -- se não houver parâmetro de imagem, continue, talvez haja uma imagem padrão definida no módulo infobox
        params.imageparameters = {}
    end
    for j, k in ipairs(params.imageparameters) do
        table.insert(images, localdata[k])
    end
    -- Images de Wikidata
    local iswikidataimage, iswikidatacaption = false
    if #images == 0 and localdata.item then
        if params.property then
            params.wikidata = {entity = localdata.item, property = params.property}
        end
        if params.wikidata then
            local wdq = params.wikidata
            wdq.excludespecial = true
            if type(wdq) == 'table' then
                wdq.entity = wdq.entity or localdata.item
                wdq.numval = wdq.numval or params.numval or 1
                images = wd.getClaims(wdq)
            end
            if type(wdq) == 'function' then
                images = params.wikidata()
                if type(images) == 'string' then
                    return images
                end -- provavelmente é um erro na mensagem request = > mostra
            end
            if (not images) then
                images = {}
            end
            if (#images > 0) and (params.wikidata.property) then
                maintenance = maintenance .. wd.addTrackingCat(params.wikidata.property)
            end

            if type(images[1]) == 'table' then
                for i, image in pairs(images) do
                    if image.mainsnak.snaktype ~= 'value' then
                        return
                    end
                    if #images == 1 then -- se apenas uma imagem, usamos a legenda (se mais duas imagens, como formatar?)
                        caption = wd.getFormattedQualifiers(images[i], {'P2096'}, {isinlang = wikiLang}) or wd.getFormattedQualifiers(images[i], {'P805'})
                        iswikidatacaption = caption ~= nil
                    end
                    images[i] = image.mainsnak.datavalue.value
                    iswikidataimage = true
                end
            end
        end
    end

--    if #images == 0 and getValue(params.captionparameter) ~= nil then
--        addMaintenanceCat("Infobox avec une légende locale sans image")
--    end
    -- Imagens por padrão
    if #images == 0 then
        if params.maintenancecat then
            addMaintenanceCat(params.maintenancecat, params.sortkey)
        end
        if params.defaultimages then
            images = params.defaultimages
            if type(images) == 'string' then
                images = {images}
            end
            upright = params.defaultimageupright
            caption = params.defaultimagecaption
            link = params.defaultimagelink
            alt = params.defaultimagealt
            if not alt and ( images[1] == 'Padrao' or images[1] == 'Padrao 2.svg' ) then
                   alt = 'uma ilustração licenciada gratuita seria bem-vinda'
            end
        end
    end
    if #images == 0 then
        return nil
    end

    upright = upright or getValue(params.uprightparameter) or params.defaultupright or "1" -- 1.2 deixa uma margem
    link = link or getValue(params.linkparameter) or params.defaultlink
    caption = caption or getValue(params.captionparameter) or params.defaultcaption
    alt = alt or getValue( params.altparameter) or params.defaultalt

--    if iswikidataimage and not iswikidatacaption and getValue(params.captionparameter) ~= nil then
--        addMaintenanceCat("Infobox avec une légende locale et une image sur Wikidata")
--    end

    -- tamanho com "size" (obsoleto)
    size = size or getValue(params.sizeparameter) or params.defaultsize -- deprecated
    if size then
        local sizevalue = size:gsub('px$', '')

        local widthonly = mw.ustring.gsub(sizevalue, 'x.*', '')
        widthonly = tonumber(widthonly)
        if type(widthonly) ~= 'number' or widthonly > 280 then
--            addMaintenanceCat("!Info caixa com tamanho da imagem muito grande")
        end

        if tonumber(sizevalue) then
            size = tostring( tonumber(sizevalue) / #images ) .. 'px'
        end
    end

    if tonumber(upright) then
        upright = tostring( tonumber(upright) / #images )
    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 ..  '[[Ficheiro:' .. image .. '|frameless'
        if size then
            imagesString = imagesString .. '|' .. size -- not a mistake, parameter is unnamed
        end
        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 and not size then
            imagesString = imagesString .. '|upright=' .. ( 1 / #images )
        end
        if image:sub(-4):lower() == '.svg' then
            imagesString = imagesString .. '|lang=' .. wikiLang
        end
        imagesString = imagesString .. ']]'

        if usedImages[image] then
            addMaintenanceCat('!Infocaixa com demasiadas imagens ideênticas')
        end
        usedImages[image] = true
    end

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

    -- Parte da legenda
    local captionobj
    if caption then
        captionobj = mw.html.create('div')
            :wikitext(caption)
            :css(params.legendstyle or {})
            :addClass("legend")
            :done()
    end

    -- separador
    local separator
    if params.separator then
        separator = p.separator(params)
    end
    return mw.html.create('div')
        :node(image)
        :node(captionobj)
        :node(separator)
        :done()
end
p.buildImages = p.buildimages

function p.buildtext(params)
    local classes = params.class or ''
    local style = {
        ['text-align'] = 'center',
        ['font-weight'] = 'bold'
    }
    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
        if params.maintenancecat then
            addMaintenanceCat(params.maintenancecat, params.sortkey)
        end
        return nil
    end
    -- separador
    local separator
    if params.separator then
        separator = p.separator(params)
    end
    local formattedtext = mw.html.create('p')
        :addClass(classes)
        :css(style)
        :wikitext(text)
        :node(separator)
        :done()
    return formattedtext
end
p.buildText = p.buildtext

function p.buildrow(params)
    local classes = params.class or ''
    local style = params.style or {}
    local valueClass = params.valueClass or ''
    local valueStyle = params.valueStyle or {}
    local value, gendernum = getValue(params.value, params)
    if(type(gendernum) == 'number') then
        if(gendernum > 1) then
            gendernum = 'p'
        else
            gendernum = 's'
        end
    end

    if type(params.wikidata) == 'table' then
        params.wikidata.wikidatalang = localdata.wikidatalang
        if (value == valueexpl) then
            value = nil
            params.wikidata.expl = false
        end
    end
    if (not value) then
        value, gendernum = getWikidataValue(params, 'wikidata')
    end

    if not value then
        value = params.defaultvalue
    end
    if value == '-' then
        return nil
    end
    if not gendernum then
        gendernum = 's' --singular indefinido
    end

    if not value then
        if params.maintenancecat then
            addMaintenanceCat(params.maintenancecat, params.sortkey)
        end
        return nil
    end

    local label = params.label
    if type(label) == 'string' then label = {default = label} end

    if type(label) == 'table' then -- Acordo do género e nome
        local onlynum = {default = 'default', s = 's', ms = 's', fs = 's', p = 'p', mp = 'p', fp = 'p', mixtep = 'p'} -- Acordo apenas nome por padrão

        label['s'] = label['s'] or params.singularlabel or label['default'] or label['ms']
        label['p'] = label['p'] or params.plurallabel or label['mp']

        label = label[gendernum] or label[onlynum[gendernum]] or label.default
    end

    if type(label) == 'function' then
            label = label(localdata, localdata.item)
    end

    -- format
    local formattedvalue = mw.html.create('div')
        :wikitext('\n' .. value) -- Oe '\n' é necessário quando o valor é uma lista que começa com '*' 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="[Mostrar]/[Esconder]", 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(classes)
        :css(style)
        :node(formattedlabel)
        :node(formattedvalue)
        :done()

    return row
end
p.buildRow = p.buildrow

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 styleI = {}
    local colspan = '2'
    styleI['padding'] = '1px'
    local 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%'
    local tabC = mw.html.create('table')
            :attr({cellspacing = '0'})
            :addClass('navigation-not-searchable')
            :css(styleT)

    local row = mw.html.create('tr')

    local color = params.color

    local style = {}
    local arrowLeft = '[[Ficheiro:Arrleft.svg|13px|alt=Precedente|link=]]'
    local arrowRight = '[[Ficheiro:Arrright.svg|13px|alt=Seguinte|link=]]'

    if color ~= 'default' then
        style['background-color'] = color
    end

    local styleTrans = {}

    local values = params.value
    local before = values['before']
    local center = values['center']
    local after = values['after']

    local widthCenter
    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(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 classes = params.class
    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(classes)
        :css(style)
        :node(formattedlabel)
        :done()

    return row
end
p.buildRow1Col = p.buildrow1col

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

    local rows = params.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('as linhas da infobox ("rows") devem ser tabelas, e ' .. 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 params.title or params.singulartitle or params.pluraltitle then
        local text
        if #rows > 1 and params.pluraltitle then
            text = params.pluraltitle
        elseif #rows == 1 and params.singulartitle then
            text = params.singulartitle
        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
p.buildTable = p.buildtable

function p.buildinvalidblock(args)
    addMaintenanceCat(i18n['default cat'])
    local text = ''
    if type(args) ~= 'table' then
        text = "Os blocos de infobox devem ser tabelas"
    else
        text = i18n["invalid block type"] .. ' : ' .. (args.type or '??')
    end
    return text
end
p.buildInvalidBlock = p.buildinvalidblock

function p.buildmap(params)

    -- paramètre d'affichage
    local maplist = getValue(params.maps)
    local pointtype = params.pointtype
    local maptype = params.maptype -- escolhe o tipo de mapa mais adequado (alívio, administrativo, etc.)
    if type(maplist) == 'function' then
        maplist = maplist(localdata, localdata.item)
    end
    local width = tonumber(params.width) or 280
    if width > 280 then
            addMaintenanceCat("!Erro de infobox - imagem muito grande")
         return 'imagem muito grande, a largura deve ser menor ou igual a 280px'
    end

        -- mostrar os dados locais
    local pointtable = {}
    local globe = params.globe
    if params.latitude then
        local lat, long
        if type(params.latitude) == 'function' then
            lat, long = params.latitude(localdata, localdata.item), params.longitude(localdata,localdata.item)
        else
            lat, long = localdata[params.latitude], localdata[params.longitude]
        end
        if lat then
            table.insert(pointtable, {latitude = lat, longitude = long})
        end
    end

        -- mostrar os dados wikidata
    local function processWDval(claim, displayformat)
        if not claim then
            return nil
        end
        local val = wd.formatSnak( claim.mainsnak )
        return {latitude = val.latitude, longitude = val.longitude, globe = val.globe, marker = displayformat.marker}
    end

    local function getWDvals(query)
        query.excludespecial = true
        query.numval = query.numval or 1
        query.entity = query.entity or localdata.item
        local claims = wd.getClaims(query)
        if (not claims) then
            return
        end
        for i, claim in ipairs(claims) do
            claim = processWDval(claim, query)
            table.insert(pointtable, claim)
        end
    end

    if (#pointtable == 0) and localdata.item and params.wikidata and (params.wikidata ~= '-') then
        for i, query in ipairs(params.wikidata) do
            if type(query) == 'function' then
                query = query()
            end
            if query then
                getWDvals(query)
            end
        end
    end

    if (not pointtable) or (#pointtable == 0) then
        return nil
    end

    local newparams = {maplist = maplist, pointtype = pointtype, maptype = maptype, width = width, item = localdata.item, pointtable = pointtable, globe = globe, marker=params.marker, default_zoom=params.default_zoom, ids = params.ids, markercolor = params.markercolor, shapecolor = params.shapecolor }
    if params.params and type(params.params) == 'table' then -- parâmetros adicionais
        for i, j in pairs(params.params) do
            newparams[i] = j
        end
    end
    return require('Module:Mapa').multimap(newparams)
end
p.buildMap = p.buildmap

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

function p.buildfooter(params)
    if not params then
        params = {}
    end

    local classes = 'navbar noprint bordered navigation-not-searchable ' .. (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.prefixedText, 'veaction=edit&section=0' ) ) .. ' ' .. i18n['edit'] .. ']'
        .. ' - [' .. tostring( mw.uri.fullUrl( page.prefixedText, 'action=edit&section=0' ) ) .. ' ' .. i18n['edit code'] .. ']'

    local itemlinkstr
    if localdata.item then
        itemlinkstr = '[[d:' .. localdata.item .. '|' .. 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 = '[[Ficheiro:Info Simple.svg|12px|link=' .. localdata.templatename .. '|' .. i18n['see doc'] .. ']]'
    -- se esta ligação nem sempre funcionar, deve adicionar uma variável para o nome da infobox recuperada pelo quadro
    local doclinkspan = mw.html.create('span')
        :css({['text-align'] = "right"})
        :wikitext(doclinkstr)
        :done()

    local footer = mw.html.create('p')
        :addClass(classes)
        :css(style)
        :node(editlinkspan)
        :node(doclinkspan)
    return footer
end
p.buildFooter = p.buildfooter

function p.buildblock(block)
    if type(block) == 'function' then
        block = block( localdata )
    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,
        ['navigator'] = p.buildnavigator,
        ['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

--[=[
Loads the templatestyles for the infobox.

TODO: FINISH loading base templatestyles here rather than in
MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).
When we do this we should clean up the inline CSS below too.
Will have to do some bizarre conversion category like with sidebar.

]=]
local function loadTemplateStyles()
    local frame = mw.getCurrentFrame()

    -- See function description
    local base_templatestyles = frame:extensionTag{
        name = 'templatestyles', args = { src = 'Module:Infobox/estilos.css' }
    }

    local templatestyles = ''
    if args['templatestyles'] then
        templatestyles = frame:extensionTag{
            name = 'templatestyles', args = { src = args['templatestyles'] }
        }
    end

    return table.concat({
        base_templatestyles,
        templatestyles
    })
end

function p.build()

    localdata = require( 'Module:Infobox/Localdata' )
    if type( localdata.item ) == 'table' then
        localdata.item = localdata.item.id
    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 localdata.item then
        local itemlink = mw.wikibase.sitelink(localdata.item)
        local pagetitle = page.prefixedText
        if (itemlink or '') ~= pagetitle then
            infoboxrank = 'secondary'
        end
    end
    localdata.infoboxrank = infoboxrank

    -- load infobox module page
    local moduledata = require('Module:Infobox/' .. localdata.modulename)
    moduledata.name = localdata.modulename
    -- defines main color
    maincolor = localdata['cor infobox'] or localdata['caixa de cor'] or moduledata.maincolor or maincolor
    secondcolor = moduledata.secondcolor or secondcolor
    thirdcolor = localdata['texto negro'] or localdata['cor texto'] or moduledata.thirdcolor or thirdcolor
    if ( #maincolor == 6 or #maincolor == 3 ) and maincolor:match( '^%x+$' ) then
        maincolor = '#' .. maincolor
    end
    if thirdcolor == 'oui' or thirdcolor == 'true' then
        thirdcolor = '#000'
    elseif thirdcolor == 'non' or thirdcolor == 'false' then
        thirdcolor = '#fff'
    end

    -- classes
    --local classes = 'infobox_v3'
    local classes = mw.getCurrentFrame():expandTemplate{ title = 'Versão classes infocaixa', args = { version = '3' } } --muda entre v2 e 3
    classes = classes .. ' large ' .. (moduledata.class or '')

    -- style
    local style = moduledata.style or {}

    -- build infobox
    infobox    :addClass(classes)
            :css(style)
    for i, j in pairs( moduledata.parts ) do
        infobox:node( p.buildblock(j) )
    end
    infobox    :node(p.buildfooter(moduledata.footer))
    infobox :node(loadTemplateStyles())
            :done()

    if CategorizacaoABeAD.hasAnyBadge() == '1' then
        maintenance = maintenance .. (CategorizacaoABeAD.badgesCategories())
    end

    return tostring(infobox) .. externaltext, maintenance
end

return p