| Este módulo está classificado como beta, e está pronto para utilização generalizada. Ele ainda é novo e deve ser utilizado com cautela, para garantir que os resultados sejam os esperados. |
Este módulo implementa caixas de mensagens como {{mbox}}, {{ambox}}, {{cmbox}}, {{tmbox}}, {{imbox}}, {{ombox}} e {{fmbox}}.
Ao ser usado a caixa 'mbox', o estilo de caixa será definido automaticamente dependendo do domínio em que for usado.
- Domínio principal: ambox
- Categoria: cmbox
- Ficheiro: imbox
- Outros domínios de conteúdo: ombox
- Páginas de discussão: tmbox
Existem diferentes formas de usar a caixa, veja nos exemplos abaixo:
{{#invoke:mbox|mbox|texto=Uso básico.}}
| Uso básico. |
{{#invoke:mbox|ambox|texto=Caixa ambox.}}
{{#invoke:mbox|ambox|tipo=estilo|texto=Caixa ambox do tipo estilo.}}
{{#invoke:mbox|ambox|pequeno=sim|texto=A ambox também pode ser usada no formato pequeno.}}
{{#invoke:mbox|tmbox|pequeno=sim|texto=A tmbox também pode ser usada no formato pequeno.}}
| A tmbox também pode ser usada no formato pequeno. |
{{#invoke:mbox|ambox|pequeno=sim|texto_pequeno=Texto quando pequeno.|imagem_pequeno=Info Sign.svg|texto=Este texto não aparece quando pequeno.}}
Quando a caixa ambox for usada na versão mobile, a caixa aparecerá reduzida mostrando somente o campo |problema=
, ou a primeira frase do campo |texto=
, ao clicar na caixa ela será exibida integralmente.
A configuração dos estilos fica no Módulo:Mbox/configuração
-- Este é um módulo para gerar predefinições de caixas de aviso como as
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
require('strict')
local getArgs
local yesno = require('Módulo:Yesno')
--------------------------------------------------------------------------------
-- funções auxiliares
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
-- Retorna duas strings, a primeira frase e o restante do texto,
-- se a primeira frase for muito grande separa na primeira vírgula
local function splitFirstPhrase(str)
local _, pos = string.find(str, "%.'* [A-Z]")
local _, b = string.find(str, "%.'* ?[<\n]")
if not pos and not b then
return str
elseif pos and b then
pos = math.min(pos, b)
else
pos = pos or b
end
return str:sub(1, pos - 1), str:sub(pos)
end
local function changeIntro(str, intro)
local change = str:match'Esta página ou sec?ção'
change = change or str:match'Esta página'
if change then
str = str:gsub(change, intro, 1)
end
return str
end
--------------------------------------------------------------------------------
-- Definição da classe MessageBox
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
for k, v in pairs(args) do
if v == '' then
args[k] = nil
end
end
obj.args = args
-- Set the title object and the namespace.
obj.title = getTitleObject(args['página']) or mw.title.getCurrentTitle()
-- Set the config for our box type.
local config = cfg[boxType]
if not config then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
config = cfg.ambox -- artigo
elseif ns == 6 then
config = cfg.imbox -- ficheiro
elseif ns == 14 then
config = cfg.cmbox -- categoria
else
if obj.title.isTalkPage then
config = cfg.tmbox -- página de discussão
else
config = cfg.ombox -- outra página de conteúdo
end
end
end
-- Usando canfiguração global em campos não informados
obj.cfg = {}
for k, v in pairs(cfg.global) do
obj.cfg[k] = v
end
for k, v in pairs(config) do
obj.cfg[k] = v
end
-- Define a estrutura interna de dados
obj.categories = {}
obj.classes = {}
obj.styles = {}
obj.categories = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Categoria:%s|%s]]', cat, sort)
else
cat = string.format('[[Categoria:%s]]', cat)
end
table.insert(self.categories, cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:addStyle(stl)
if type(stl) == 'table' then
for k, v in pairs(stl) do
self.styles[k] = v
end
end
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Obtém os dados de configuração
self.type = args.tipo
local typeData = cfg.tipos[self.type]
typeData = typeData or cfg.tipos[cfg.tipoPadrao]
-- Verifica se esta usando modo pequeno
self.isSmall = cfg.permitePequeno and
(cfg.paramPequeno and args.pequeno == cfg.paramPequeno or
not cfg.paramPequeno and yesno(args.pequeno))
self.text = self.isSmall and args['texto_pequeno'] or args.texto
self.issue = args.problema
self.fix = args.conserto
self.name = args.nome
self.useCollapsibleTextFields = cfg.modoCompacto
-- Verifica se a predefinição foi incorretamente substituida
self.isSubstituted = args.subst == 'SUBST'
if self.isSubstituted then
self:addCat'!Páginas com predefinições substituídas incorretamente'
end
-- Adiciona atributos estilos e classes
self.id = args.id
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
self:addStyle(cfg.estiloBase)
self:addStyle(typeData.estilo)
if self.isSmall and cfg.estiloPequeno then
self:addStyle(cfg.estiloPequeno)
end
self.attrs = args.attrs
-- Verifica se está na página da predefinição que usa o módulo e adiciona categoria
if self.title.namespace == 10 and cfg.catPredef then
if not cfg.catPredefRequerNome then
local xmbox = mw.getCurrentFrame():getParent()
local template = xmbox and xmbox:getParent()
if template
and template.getTitle() == self.title.fullText
and not self.title.isSubpage
then
self:addCat(cfg.catPredef)
end
elseif self.name and mw.title.equals(self.name, self.title.fullText) then
self:addCat(cfg.catPredef)
end
end
-- Muda o inicio do texto se for passado o parâmetro seção ou uso=seção
local intro
local masc = {['artigo']='Este', ['portal']='Este', ['tópico']='Este', ['módulo']='Este',
['livro']='Este', ['ficheiro']='Este', ['arquivo']='Este'}
if args['seção'] or args['secção'] then
local sect = args['seção'] or args['secção']
if sect:match'^[A-Z]' or sect:match' ' then
intro = sect
elseif yesno(sect) == true then
intro = 'Esta seção'
else
intro = (masc[sect] or 'Esta') .. ' ' .. sect
end
if self.text then
self.text = changeIntro(self.text, intro)
end
if self.issue then
self.issue = changeIntro(self.issue, intro)
end
end
-- Ligação para página de discussão
local talk = args['discussão']
if talk then
local talkText = 'Veja discussão relacionada '
if talk:match'^[^#]+:' then
local link, text = talk:match'^([^#]+)#(.+)$'
self.talk = talkText ..
'em [[' .. (link and link .. '|' .. text or talk) .. ']].'
else
local link = self.title.talkPageTitle
self.talk = link and talkText ..
'na [[' .. tostring(link) .. '#' .. talk .. '|página de discussão]].'
end
end
-- Linha abaixo do texto e imagem
self.below = args.abaixo
-- Imagem
if not cfg.nenhumaImagem or args.imagem ~= cfg.nenhumaImagem then
local image = self.isSmall and args.imagem_pequeno or args.imagem
local img = image and image:match'%[%[%w+:[^%]|]+%.%a%a%a%a?|%d+px'
if img then
self.image = img .. '|link=|alt=]]'
else
img = image and image:match'^[%w -%(%)]+%.%a%a%a%a?$' or typeData.imagem
if img then
local imageSize = self.isSmall
and (cfg.tamanhoImagemPequeno or '30x30px')
or '40x40px'
self.image = string.format('[[Ficheiro:%s|%s|link=|alt=]]', img
or 'Info non-talk.png', imageSize)
end
end
end
if args.imagem_direita then
local img = args.imagem_direita:match'%[%[%w+:[^%]|]+%.%a%a%a%a?|%d+px'
if img then
self.imageRight = img .. '|link=|alt=]]'
else
img = args.imagem_direita:match'^[%w -%(%)]+%.%a%a%a%a?$' or typeData.imagem
if img then
local imageSize = self.isSmall
and (cfg.tamanhoImagemPequeno or '30x30px')
or '40x40px'
self.imageRight = string.format('[[Ficheiro:%s|%s|link=|alt=]]',
img, imageSize)
end
end
end
-- A FAZER: criar um módulo para categorizar por data e assunto como a
-- {{Manutenção/Categorização por assunto}} e chamá-lo aqui,
-- por enquanto a data só está sendo adicionada no final do texto
if args.data and not (self.text and self.text:match'%(desde ') then
self.date = '<small>(desde ' .. args.data .. ')</small>'
end
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'A predefinição <code>%s[[Predefinição:%s|%s]]%s</code> foi incorretamente substituída.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Cria a tabela
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:css(self.styles)
:attr('role', 'presentation')
if self.attrs then
boxTable:attr(self.attrs)
end
-- Adiciona a imagem
local row = boxTable:tag('tr')
if self.image then
local imageCell = row:tag('td')
imageCell:css{['width']='52px', ['padding']='5px 0 5px 8px', ['text-align']='center'}
if self.useCollapsibleTextFields then
imageCell:addClass('mbox-image')
end
imageCell:wikitext(self.image)
end
-- Adiciona o texto
local textCell = row:tag('td')
textCell:css{padding='5px 12px'}
if self.useCollapsibleTextFields then
-- Caixas com classe ambox têm uma função de ocultar parte do texto
-- e abrir o texto todo ao clicar na versão mobile
textCell:addClass('mbox-text')
local textShow, textHide = self.issue, self.fix
if not textShow and self.text then
textShow, textHide = splitFirstPhrase(self.text)
end
local textCellSpan = textCell:tag('span')
textCellSpan:addClass('mbox-text-span')
textCellSpan:wikitext(textShow)
textCellSpan:wikitext(self.date and ' ' .. self.date .. ' ')
if textHide then
textCellSpan:tag('span')
:addClass('hide-when-compact')
:wikitext(self.talk and ' ' .. self.talk .. ' ')
:wikitext(textHide)
else
textCellSpan:wikitext(self.talk and ' ' .. self.talk)
end
else
textCell:wikitext(self.text)
textCell:wikitext(self.date and ' ' .. self.date)
textCell:wikitext(self.talk and ' ' .. self.talk)
end
-- Imagem direita
if self.imageRight then
local imageCell = row:tag('td')
imageCell:css{['width']='52px', ['padding']='5px 8px 5px 0', ['text-align']='center'}
if self.useCollapsibleTextFields then
imageCell:addClass('mbox-image')
end
imageCell:wikitext(self.imageRight)
end
-- Linha de baixo
if self.below then
local row = boxTable:tag('td')
row:attr('colspan', tostring(1 + (self.image and 1 or 0) + (self.imageRight and 1 or 0)))
row:addClass(self.useCollapsibleTextFields and 'hide-when-compact' or nil)
row:wikitext(self.below)
end
-- Adiciona categorias
root:wikitext(table.concat(self.categories))
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData('Módulo:mbox/configuração'))
box:setParameters()
return box:export()
end
function mt.__index(t, k)
return function (frame)
-- Coleta os argumentos como o Módulo:Arguments, porem mais leve
local args = {}
local parent = frame:getParent()
if parent then
for k, v in pairs(parent.args) do
args[k] = v
end
end
for k, v in pairs(frame.args) do
args[k] = v
end
return t.main(k, args)
end
end
return setmetatable(p, mt)