Módulo:Sidebar
Aspeto
![]() | Este módulo está classificado como alfa. Ele está pronto para aceitar dados de terceiros, e pode ser utilizado em algumas páginas para ver se aparecem problemas, mas deve ser vigiado. Sugestões para novas funções ou alterações dos seus mecanismos de dados de entrada e saída são bem-vindas. |
![]() | Este módulo utiliza TemplateStyles: |
![]() | Este módulo depende dos seguintes outros módulos: |
Este módulo implementa as templates {{sidebar}} e {{sidebar with collapsible lists}}. Ver as páginas das predefinições individuais para documentação.
require('strict')
local cfg = mw.loadData('Módulo:Sidebar/configuração')
local p = {}
local getArgs = require('Módulo:Arguments').getArgs
--[[
Categoriza predefinições e módulos de chamada com um parâmetro 'style' de qualquer tipo
para rastreamento para conversão em TemplateStyles..
TODO após uma longa limpeza: captura barras laterais em outros espaços nomeados além de Predefinição e Módulo.
TODO provavelmente desejaria remover /log e /archive como o CS1 faz
]]
local function categorizeTemplatesWithInlineStyles(args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 and title.namespace ~= 828 then return '' end
for _, pattern in ipairs (cfg.i18n.pattern.uncategorized_conversion_titles) do
if title.text:match(pattern) then return '' end
end
for key, _ in pairs(args) do
if mw.ustring.find(key, cfg.i18n.pattern.style_conversion) or key == 'width' then
return cfg.i18n.category.conversion
end
end
end
--[[
Para compatibilidade com a implementação original d {{Sidebar with collapsible lists}}, que passou alguns parâmetros por meio de {{#if}} para aparar seus
espaços em branco. Isso também acionou o comportamento de nova linha automática.
]]
-- Ver ([[meta:Help:Newlines and spaces#Automatic newline]])
local function trimAndAddAutomaticNewline(s)
s = mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")
if mw.ustring.find(s, '^[#*:;]') or mw.ustring.find(s, '^{|') then
return '\n' .. s
else
return s
end
end
--[[
Verifica se uma barra lateral tem uma barra lateral de subgrupo.
]]
local function hasSubgroup(s)
if mw.ustring.find(s, cfg.i18n.pattern.subgroup) then
return true
else
return false
end
end
local function has_navbar(navbar_mode, sidebar_name)
return navbar_mode ~= cfg.i18n.navbar_none and
navbar_mode ~= cfg.i18n.navbar_off and
(
sidebar_name or
mw.getCurrentFrame():getParent():getTitle():gsub(cfg.i18n.pattern.sandbox, '') ~=
cfg.i18n.title_not_to_add_navbar
)
end
local function has_list_class(args, htmlclass)
local patterns = {
'^' .. htmlclass .. '$',
'%s' .. htmlclass .. '$',
'^' .. htmlclass .. '%s',
'%s' .. htmlclass .. '%s'
}
for arg, value in pairs(args) do
if type(arg) == 'string' and mw.ustring.find(arg, 'class') then
for _, pattern in ipairs(patterns) do
if mw.ustring.find(args[arg] or '', pattern) then
return true
end
end
end
end
return false
end
-- Existem muitas classes de listas disponíveis, então adicionamos seus TemplateStyles
local function add_list_styles(args)
local frame = mw.getCurrentFrame()
local function add_list_templatestyles(htmlclass, templatestyles)
if has_list_class(args, htmlclass) then
return frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
}
else
return ''
end
end
local plainlist_styles = add_list_templatestyles('plainlist', cfg.i18n.plainlist_templatestyles)
local hlist_styles = add_list_templatestyles('hlist', cfg.i18n.hlist_templatestyles)
-- uma segunda solução alternativa para [[phab:T303378]]
-- quando esse problema for corrigido, podemos realmente usar has_navbar para não emitir a
-- tag aqui se quisermos
if has_navbar(args.navbar, (args.name or args.nome)) and hlist_styles == '' then
hlist_styles = frame:extensionTag{
name = 'templatestyles', args = { src = cfg.i18n.hlist_templatestyles}
}
end
-- hlist -> plainlist é o melhor esforço para preservar a antiga ordenação Common.css. [hlist_note]
return hlist_styles .. plainlist_styles
end
-- solução alternativa [[phab:T303378]]
-- para cada argumento: encontra todos os marcadores de tira de templatestyles, insere-os em uma
-- tabela. então remove todos os marcadores de templatestyles do argumento
local function move_hiding_templatestyles(args)
local gfind = string.gfind
local gsub = string.gsub
local templatestyles_markers = {}
local strip_marker_pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)'
for k, arg in pairs(args) do
for marker in gfind(arg, strip_marker_pattern) do
table.insert(templatestyles_markers, marker)
end
args[k] = gsub(arg, strip_marker_pattern, '')
end
return templatestyles_markers
end
--[[
Função principal da barra lateral. Pega frame, args e uma collapsibleClass opcional.
A collapsibleClass é e deve ser usada apenas para barras laterais com listas
collapsíveis, como em p.collapsible.
]]
function p.sidebar(frame, args, collapsibleClass)
if not args then args = getArgs(frame) end
local hiding_templatestyles = table.concat(move_hiding_templatestyles(args))
local root = mw.html.create()
local child = (args.child or args.filha) and mw.text.trim(args.child or args.filha) == cfg.i18n.child_yes
root = root:tag('table')
if not child then
root
:addClass(cfg.i18n.class.sidebar)
-- força collapsibleclass a ser sidebar-collapse, caso contrário, não produzirá nada
:addClass(collapsibleClass == cfg.i18n.class.collapse and cfg.i18n.class.collapse or nil)
:addClass('nomobile')
:addClass((args.float or args['flutuar'] or args['lado']) == cfg.i18n.float_none and cfg.i18n.class.float_none or nil)
:addClass((args.float or args['flutuar'] or args['lado']) == cfg.i18n.float_left and cfg.i18n.class.float_left or nil)
:addClass(args.wraplinks ~= cfg.i18n.wrap_true and cfg.i18n.class.wraplinks or nil)
:addClass(args.bodyclass or args['classe-corpo'] or args.class or args.classe)
:css('width', args.width or args.largura or nil)
:cssText(args.bodystyle or args['estilo-corpo'] or args.style or args.estilo)
if (args.outertitle or args['título-externo'] or args['título-exterior'] or args['cabeçalho']) then
root
:tag('caption')
:addClass(cfg.i18n.class.outer_title)
:addClass(args.outertitleclass or args['classe-título-externo'] or args['classe-título-exterior'] or args['classe-cabeçalho'])
:cssText(args.outertitlestyle or args['estilo-título-externo'] or args['estilo-título-exterior'] or args['estilo-cabeçalho'])
:wikitext(args.outertitle or args['título-externo'] or args['título-exterior'] or args['cabeçalho'])
end
if (args.topimage or args['imagem-topo'] or args['imagem2']) then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(cfg.i18n.class.top_image)
:addClass(args.topimageclass or args['classe-imagem-topo'] or args['classe-imagem2'])
:cssText(args.topimagestyle or args['estilo-imagem-topo'] or args['estilo-imagem2'])
:wikitext(args.topimage or args['imagem-topo'] or args['imagem2'])
if (args.topcaption or args['legenda-topo'] or args['imagem_legenda2']) then
imageCell
:tag('div')
:addClass(cfg.i18n.class.top_caption)
:cssText(args.topcaptionstyle or args['estilo-legenda-topo'] or args['estilo-imagem_legenda2'])
:wikitext(args.topcaption or args['legenda-topo'] or args['imagem_legenda2'])
end
end
if (args.pretitle or args['pré-título']) then
root
:tag('tr')
:tag('td')
:addClass(args.topimage and cfg.i18n.class.pretitle_with_top_image
or cfg.i18n.class.pretitle)
:addClass(args.pretitleclass or args['classe-pré-título'])
:cssText(args.basestyle or args['estilo-base'])
:cssText(args.pretitlestyle or args['estilo-pré-título'])
:wikitext(args.pretitle or args['pré-título'])
end
else
root
:addClass(cfg.i18n.class.subgroup)
:addClass(args.bodyclass or args['classe-corpo'] or args.class or args.classe)
:cssText(args.bodystyle or args['estilo-corpo'] or args.style or args.estilo)
end
if (args.title or args['título']) then
if child then
root
:wikitext(args.title or args['título'])
else
root
:tag('tr')
:tag('th')
:addClass((args.pretitle or args['pré-título']) and cfg.i18n.class.title_with_pretitle
or cfg.i18n.class.title)
:addClass(args.titleclass or args['classe-título'])
:css('font-size', '1.5em') -- *
:cssText(args.basestyle or args['estilo-base'])
:cssText(args.titlestyle or args['estilo-título'])
:wikitext(args.title or args['título'])
end
end
if (args.image or args.imagem) then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(cfg.i18n.class.image)
:addClass(args.imageclass or args['classe-imagem'])
:cssText(args.imagestyle or args['estilo-imagem'])
:wikitext(args.image or args.imagem)
if (args.caption or args.legenda or args['imagem_legenda']) then
imageCell
:tag('div')
:addClass(cfg.i18n.class.caption)
:cssText(args.captionstyle or args['estilo-legenda'] or args['estilo-imagem_legenda'])
:wikitext(args.caption or args.legenda or args['imagem_legenda'])
end
end
if (args.above or args.acima) then
root
:tag('tr')
:tag('td')
:addClass(cfg.i18n.class.above)
:addClass(args.aboveclass or args['classe-acima'])
:cssText(args.abovestyle or args['estilo-acima'])
:newline() -- nova linha necessária para que os marcadores funcionem
:wikitext(args.above or args.acima)
end
local rowNums = {}
for k, v in pairs(args) do
k = '' .. k
local num = k:match('^heading(%d+)$') or k:match('^rótulo(%d+)$') or k:match('^content(%d+)$') or k:match('^conteúdo(%d+)$') or k:match('^dados(%d+)$')
if num then table.insert(rowNums, tonumber(num)) end
end
table.sort(rowNums)
-- remove duplicatas da lista (por exemplo, 3 será duplicado se ambos heading3
-- e content3 forem especificados)
for i = #rowNums, 1, -1 do
if rowNums[i] == rowNums[i - 1] then
table.remove(rowNums, i)
end
end
for i, num in ipairs(rowNums) do
local heading = args['heading' .. num] or args['rótulo' .. num]
if heading then
root
:tag('tr')
:tag('th')
:addClass(cfg.i18n.class.heading)
:addClass(args.headingclass or args['classe-rótulo'])
:addClass(args['heading' .. num .. 'class'] or args['classe-rótulo' .. num])
:cssText(args.basestyle or args['estilo-base'])
:cssText(args.headingstyle or args['estilo-rótulo'])
:cssText(args['heading' .. num .. 'style'] or args['estilo-rótulo' .. num])
:newline()
:wikitext(heading)
end
local content = args['content' .. num] or args['conteúdo' .. num] or args['dados' .. num]
if content then
root
:tag('tr')
:tag('td')
:addClass(hasSubgroup(content) and cfg.i18n.class.content_with_subgroup
or cfg.i18n.class.content)
:addClass(args.contentclass or args['classe-conteúdo'] or args['classe-dados'])
:addClass(args['content' .. num .. 'class'] or args['classe-conteúdo' .. num] or args['classe-dados' .. num])
:cssText(args.contentstyle or args['estilo-conteúdo'] or args['estilo-dados'])
:cssText(args['content' .. num .. 'style'] or args['estilo-conteúdo' .. num] or args['estilo-dados' .. num])
:newline()
:wikitext(content)
:done()
-- Sem uma quebra de linha após </td>, uma lista aninhada como
-- "* {{hlist| ...}}" não é analisada corretamente.
:newline()
end
end
if (args.below or args.abaixo) then
root
:tag('tr')
:tag('td')
:addClass(cfg.i18n.class.below)
:addClass(args.belowclass or args['classe-abaixo'])
:cssText(args.belowstyle or args['estilo-abaixo'])
:newline()
:wikitext(args.below or args.abaixo)
end
if not child and has_navbar(args.navbar, (args.name or args.nome)) then
root
:tag('tr')
:tag('td')
:addClass(cfg.i18n.class.navbar)
:cssText(args.navbarstyle or args['estilo-navbar'])
:wikitext(require('Módulo:Navbar')._navbar{
(args.name or args.nome),
mini = 1,
fontstyle = args.navbarfontstyle or args['estilo-fonte-navbar']
})
end
local base_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = cfg.i18n.templatestyles }
}
local templatestyles = ''
if args['templatestyles'] and args['templatestyles'] ~= '' then
templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['templatestyles'] }
}
end
local child_templatestyles = ''
if args['child templatestyles'] and args['child templatestyles'] ~= '' then
child_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['child templatestyles'] }
}
end
local grandchild_templatestyles = ''
if args['grandchild templatestyles'] and args['grandchild templatestyles'] ~= '' then
grandchild_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['grandchild templatestyles'] }
}
end
return table.concat({
add_list_styles(args), -- ver [hlist_note] acima sobre a ordenação
base_templatestyles,
templatestyles,
child_templatestyles,
grandchild_templatestyles,
hiding_templatestyles,
tostring(root),
(child and cfg.i18n.category.child or ''),
categorizeTemplatesWithInlineStyles(args)
})
end
local function list_title(args, is_centered_list_titles, num)
local title_text = trimAndAddAutomaticNewline(args['list' .. num .. 'title'] or args['título-lista' .. num]
or cfg.i18n.default_list_title)
local title
if is_centered_list_titles then
-- recolhível pode ser complicado, então fornece alguma CSS/HTML para dar suporte
title = mw.html.create('div')
:addClass(cfg.i18n.class.list_title_centered)
:wikitext(title_text)
else
title = mw.html.create()
:wikitext(title_text)
end
local title_container = mw.html.create('div')
:addClass(cfg.i18n.class.list_title)
-- não /precisa/ de uma listnumtitleclass porque você pode fazer
-- .templateclass .listnumclass .sidebar-list-title
:addClass(args.listtitleclass or args['classe-título-lista'])
:cssText(args.basestyle or args['estilo-base'])
:cssText(args.listtitlestyle or args['estilo-título-lista'])
:cssText('color: var(--color-base)')
:cssText(args['list' .. num .. 'titlestyle'] or args['estilo-título-lista' .. num])
:node(title)
:done()
return title_container
end
--[[Ponto de entrada principal para barra lateral com listas recolhíveis.
Faz o trabalho de criar as próprias listas recolhíveis e incluí-las
nos args.
]]
function p.collapsible(frame)
local args = getArgs(frame)
if not (args.name or args.nome) and
frame:getParent():getTitle():gsub(cfg.i18n.pattern.collapse_sandbox, '') ==
cfg.i18n.collapse_title_not_to_add_navbar then
args.navbar = cfg.i18n.navbar_none
end
local contentArgs = {}
local is_centered_list_titles = false
if args['centered list titles'] and args['centered list titles'] ~= '' then
is_centered_list_titles = true
end
for k, v in pairs(args) do
local num = string.match(k, '^list(%d+)$') or string.match(k, '^lista(%d+)$') or string.match(k, '^lista(%d+)-nome')
if num then
local expand = args.expanded and
(args.expanded == 'all' or args.expanded == 'tudo'
or args.expanded == 'todo' or args.expanded == 'toda'
or args.expanded == 'todos' or args.expanded == 'todas'
or args.expanded == (args['list' .. num .. 'name'] or args['lista' .. num .. 'nome'] or args['lista' .. num .. '-nome'])) or args.expandir and
(args.expandir == 'all' or args.expandir == 'tudo'
or args.expandir == 'todo' or args.expandir == 'toda'
or args.expandir == 'todos' or args.expandir == 'todas'
or args.expandir == (args['list' .. num .. 'name'] or args['lista' .. num .. 'nome'] or args['lista' .. num .. '-nome'])) or args.expandida and
(args.expandida == 'all' or args.expandida == 'tudo'
or args.expandida == 'todo' or args.expandida == 'toda'
or args.expandida == 'todos' or args.expandida == 'todas'
or args.expandida == (args['list' .. num .. 'name'] or args['lista' .. num .. 'nome'] or args['lista' .. num .. '-nome']))
local row = mw.html.create('div')
row
:addClass(cfg.i18n.class.list)
:addClass('mw-collapsible')
:addClass((not expand) and 'mw-collapsed' or nil)
:addClass(args['list' .. num .. 'class'] or args['classe-lista' .. num])
:cssText(args.listframestyle or args['estilo-quadro-lista'])
:cssText(args['list' .. num .. 'framestyle'] or args['estilo-quadro-lista' .. num])
:node(list_title(args, is_centered_list_titles, num))
:tag('div')
:addClass(cfg.i18n.class.list_content)
:addClass('mw-collapsible-content')
:addClass(args.listclass or args['classe-lista'])
:cssText(args.liststyle or args['estilo-lista'])
:cssText(args['list' .. num .. 'style'] or args['estilo-lista' .. num])
:wikitext(trimAndAddAutomaticNewline(args['list' .. num] or args['lista' .. num]))
contentArgs['content' .. num] = tostring(row)
end
end
for k, v in pairs(contentArgs) do
args[k] = v
end
return p.sidebar(frame, args, cfg.i18n.class.collapse)
end
return p