Модуль : HtmlBuilder

Материал из Википедии ? свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация

Копия английского модуля (от 06.04.2013)

Это экспериментальный модуль для построения HTML-разметки (например, инфобоксы, навигационные шаблоны), с помощью текучего интерфейса .

HtmlBuilder даёт возможность построить HTML-разметку и CSS-разметку созданием дерева узлов аналогичного Document Object Model . В результате получается код более понятный и совместимый, чем при просто конкатенации строк. Он предоставляет текучий интерфейс , которой должно быть знаком любому пользователю JQuery .

Usage

First, you need to load the module:

local HtmlBuilder = require('Module:HtmlBuilder')

Next, create the root HtmlBuilder instance:

local builder = HtmlBuilder.create()

Then, you can build HTML using the methods of the HtmlBuilder instance, listed below.

Finally, get the resulting HTML markup as a string:

local s = tostring(builder)

Methods

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() Returns the parent node under which the current node was created. Like jQuery.end , this is a convenience function to allow the construction of several child nodes to be chained together into a single statement.

allDone

builder = div.allDone() Like .done() , but traverses all the way to the root node of the tree and returns it.

wikitext

div.wikitext('This is some [[example]] text.') Appends some markup to the node. It may include plain text, wiki markup, and even HTML markup.

newline

div.newline() Appends a newline character to the node. Equivalent to .wikitext('\n') .

attr

div.attr('title', 'Attr value') Set an HTML attribute on the node.

css

div.css('color', '#f00') Set a CSS property to be added to the node's style attribute.

cssText

div.cssText('color:#f00; font-size:1.5em') Add some raw CSS to the node's style attribute. This is typically used when a template allows some CSS to be passed in as a parameter, such as the liststyle parameter of {{ Navbox }} .

addClass

div.addClass('even') Adds a class name to the node's class attribute. Spaces will be automatically added to delimit each added class name.

Examples

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>'


For more examples, please see the test cases page and the test cases results .

-- Копия английского модуля (от 16.07.2014)

-- Экспериментальный модуль для построения HTML-разметки

-- (например, инфобоксы, навигационные шаблоны), 

-- с помощью текучего интерфейса


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