Módulo:HtmlBuilder
Descrição
O HtmlBuilder fornece uma maneira de construir marcação complexa em HTML e CSS criando uma árvore de nós, parecida com o Modelo de Objeto de Documentos (DOM). O resultado é uma lista de códigos que são mais compreensíveis e fáceis de manter do que se fosse simplesmente feita a concatenação de strings umas com as outras. Ele oferece uma interface fluída que deve parecer familiar a qualquer usuário de jQuery.
Uso
Primeiro, é preciso carregar o módulo:
local HtmlBuilder = require('Module:HtmlBuilder')
Em seguida, crie a instância raiz do HtmlBuilder:
local builder = HtmlBuilder.create()
Depois, você pode construir HTML utilizando os métodos da instância do HtmlBuilder, listados abaixo.
Finalmente, obtenha a marcação HTML resultante em forma de string:
local s = tostring(builder)
Métodos
To allow chaining, all methods return a reference to the builder, unless otherwise stated.
tag
local div = builder.tag('div')
Appends a new child node to the builder, and returns an HtmlBuilder instance representing that new node.
done
builder = div.done()
Retorna o nó pai sob o qual foi criado o nó atual. Tal como jQuery.end, este é uma função de conveniência para possibilitar o encadeamento da construção de vários nós filhos em uma única declaração.
allDone
builder = div.allDone()
Como .done()
, mas percorre todo o caminho até o nó raiz da árvore e então retorna-o.
wikitext
div.wikitext('This is some [[example]] text.')
Adiciona alguma marcação ao nó. Ela pode incluir texto simples, código wiki, e até mesmo código HTML.
newline
div.newline()
Adiciona um caractere de nova linha ao nó. Equivalente a .wikitext('\n')
.
attr
div.attr('title', 'Attr value')
Define um atributo HTML no nó.
css
div.css('color', '#f00')
Define uma propriedade CSS a ser inserida no atributo style
do nó.
cssText
div.cssText('color:#f00; font-size:1.5em')
Adiciona um código em sintaxe CSS ao atributo style
do nó. Isso geralmente é utilizado quando uma predefinição permite que seja passado CSS como parâmetro, tal como o parâmetro liststyle
da {{Navbox}}.
addClass
div.addClass('even')
Inclui o nome de uma classe no atributo class
do nó. Os espaços que delimitam o nome de cada classe são inseridos automaticamente.
Exemplos
local HtmlBuilder = require('Module:HtmlBuilder')
local root = HtmlBuilder.create()
root
.wikitext('Lorem ')
.tag('span')
.css('color', 'red')
.attr('title', 'ipsum dolor')
.wikitext('sit amet')
.done()
.tag('div')
.wikitext('consectetur adipisicing')
local s = tostring(root)
-- s = 'Lorem <span style="color:red;" title="ipsum dolor">sit amet</span><div>consectetur adipisicing</div>'
Para mais exemplo, por favor veja
a página de testes em inglês e os resultados dos testes.
-- Module for building complex HTML (e.g. infoboxes, navboxes) using a fluent interface.
local HtmlBuilder = {}
local metatable = {}
metatable.__index = function(t, key)
local ret = rawget(t, key)
if ret then
return ret
end
ret = metatable[key]
if type(ret) == 'function' then
return function(...)
return ret(t, ...)
end
else
return ret
end
end
metatable.__tostring = function(t)
local ret = {}
t._build(ret)
return table.concat(ret)
end
metatable._build = function(t, ret)
if t.tagName then
table.insert(ret, '<' .. t.tagName)
for i, attr in ipairs(t.attributes) do
table.insert(ret, ' ' .. attr.name .. '="' .. attr.val .. '"')
end
if #t.styles > 0 then
table.insert(ret, ' style="')
for i, prop in ipairs(t.styles) do
if type(prop) == 'string' then -- added with cssText()
table.insert(ret, prop .. ';')
else -- added with css()
table.insert(ret, prop.name .. ':' .. prop.val .. ';')
end
end
table.insert(ret, '"')
end
if t.selfClosing then
table.insert(ret, ' /')
end
table.insert(ret, '>')
end
for i, node in ipairs(t.nodes) do
if node then
if type(node) == 'table' then
node._build(ret)
else
table.insert(ret, tostring(node))
end
end
end
if t.tagName and not t.unclosed and not t.selfClosing then
table.insert(ret, '</' .. t.tagName .. '>')
end
end
metatable.node = function(t, builder)
if builder then
table.insert(t.nodes, builder)
end
return t
end
metatable.wikitext = function(t, ...)
local vals = {...}
for i = 1, #vals do
if vals[i] then
table.insert(t.nodes, vals[i])
end
end
return t
end
metatable.newline = function(t)
table.insert(t.nodes, '\n')
return t
end
metatable.tag = function(t, tagName, args)
args = args or {}
args.parent = t
local builder = HtmlBuilder.create(tagName, args)
table.insert(t.nodes, builder)
return builder
end
local function getAttr(t, name)
for i, attr in ipairs(t.attributes) do
if attr.name == name then
return attr
end
end
end
metatable.attr = function(t, name, val)
if type(val) == 'string' or type(val) == 'number' then
-- if caller sets the style attribute explicitly, then replace all styles previously added with css() and cssText()
if name == 'style' then
t.styles = {val}
return t
end
local attr = getAttr(t, name)
if attr then
attr.val = val
else
table.insert(t.attributes, {name = name, val = val})
end
end
return t
end
metatable.addClass = function(t, class)
if class then
local attr = getAttr(t, 'class')
if attr then
attr.val = attr.val .. ' ' .. class
else
t.attr('class', class)
end
end
return t
end
metatable.css = function(t, name, val)
if type(val) == 'string' or type(val) == 'number' then
for i, prop in ipairs(t.styles) do
if prop.name == name then
prop.val = val
return t
end
end
table.insert(t.styles, {name = name, val = val})
end
return t
end
metatable.cssText = function(t, css)
if css then
table.insert(t.styles, css)
end
return t
end
metatable.done = function(t)
return t.parent or t
end
metatable.allDone = function(t)
while t.parent do
t = t.parent
end
return t
end
function HtmlBuilder.create(tagName, args)
args = args or {}
local builder = {}
setmetatable(builder, metatable)
builder.nodes = {}
builder.attributes = {}
builder.styles = {}
builder.tagName = tagName
builder.parent = args.parent
builder.unclosed = args.unclosed or false
builder.selfClosing = args.selfClosing or false
return builder
end
return HtmlBuilder