توضیحات این پودمان می‌تواند در پودمان:AlborzSports/توضیحات قرار گیرد.

--------------------------------------------------------------------------------
-- Module:AlborzSports
-- Wiki Alborz Sports Information System
-- Version 3.0
--------------------------------------------------------------------------------

local p = {}

--------------------------------------------------------------------------------
-- LOAD DATA
--------------------------------------------------------------------------------

local data = mw.loadData("Module:AlborzSports/Data")

--------------------------------------------------------------------------------
-- CONFIGURATION
--------------------------------------------------------------------------------

local INFOBOX_CLASS = data.meta.class or "infobox sport-infobox"

local DEFAULT_IMAGE_WIDTH =
    data.defaults.image_width or
    data.meta.imageWidth or
    "250px"


--------------------------------------------------------------------------------
-- HELPERS
--------------------------------------------------------------------------------

local function clean(value)

    if not value then
        return nil
    end

    value = mw.text.trim(value)

    if value == "" then
        return nil
    end

    return value

end


--------------------------------------------------------------------------------
-- ARGUMENT NORMALIZATION
--------------------------------------------------------------------------------

local function normalizeArgs(frame)

    local args = {}

    for key, value in pairs(frame.args) do

        local cleanKey = mw.text.trim(tostring(key))

        local cleanValue = clean(value)

        if cleanValue then

            local field =
                data.lookup[cleanKey] or
                cleanKey

            args[field] = cleanValue

        end

    end

    return args

end


--------------------------------------------------------------------------------
-- ENTITY DETECTION
--------------------------------------------------------------------------------

local function detectEntity(args)

    local entity = args.entity_type


    if entity then

        if data.entities[entity] then
            return entity
        end

    end


    local typeValue = args.type


    if typeValue then

        for key, value in pairs(data.lookup) do

            if key == typeValue then

                if data.entities[value] then
                    return value
                end

            end

        end

    end


    return data.defaults.entity_type or "player"

end


--------------------------------------------------------------------------------
-- GET ENTITY DATA
--------------------------------------------------------------------------------

local function getEntity(entityType)

    if data.entities[entityType] then

        return data.entities[entityType]

    end


    return data.entities.player

end


--------------------------------------------------------------------------------
-- FIELD VALUE
--------------------------------------------------------------------------------

local function getValue(args, field)

    local value = args[field]


    if value then

        return value

    end


    return nil

end


--------------------------------------------------------------------------------
-- FIELD LABEL
--------------------------------------------------------------------------------

local function getLabel(field)

    if data.fieldDefinitions[field] then

        return data.fieldDefinitions[field].label

    end


    return field

end
--------------------------------------------------------------------------------
-- TITLE RENDERER
--------------------------------------------------------------------------------

local function renderTitle(box, entityType, args)

    local title =
        args.name or
        data.entities[entityType].title or
        data.meta.title


    box
        :tag("th")
        :attr("colspan", "2")
        :addClass("infobox-title")
        :wikitext(title)

end


--------------------------------------------------------------------------------
-- IMAGE RENDERER
--------------------------------------------------------------------------------

local function renderImage(box, args)

    local image = args.image


    if not image then
        return
    end


    local width =
        args.image_width or
        DEFAULT_IMAGE_WIDTH


    local imageHtml =

        mw.getCurrentFrame():extensionTag(
            "imagemap",
            ""
        )


    local file =

        mw.html.create("div")
        :addClass("infobox-image")


    file
        :wikitext(
            string.format(
                "[[پرونده:%s|%s]]",
                image,
                width
            )
        )


    if args.caption then

        file
            :tag("div")
            :addClass("infobox-caption")
            :wikitext(args.caption)

    end


    box
        :tag("tr")
        :tag("td")
        :attr("colspan", "2")
        :node(file)

end


--------------------------------------------------------------------------------
-- SECTION HEADER RENDERER
--------------------------------------------------------------------------------

local function renderSectionHeader(box, layout)

    local title =
        data.layoutTitles[layout]


    if not title then
        return
    end


    box
        :tag("tr")
        :tag("th")
        :attr("colspan", "2")
        :addClass("infobox-header")
        :wikitext(title)

end


--------------------------------------------------------------------------------
-- FIELD RENDERER
--------------------------------------------------------------------------------

local function renderField(box, field, value)


    if not value then
        return
    end


    local label =
        getLabel(field)


    local row =
        box
            :tag("tr")


    row
        :tag("th")
        :wikitext(label)


    row
        :tag("td")
        :wikitext(value)

end


--------------------------------------------------------------------------------
-- SPECIAL FIELD RENDERER
--------------------------------------------------------------------------------

local function renderSpecialField(box, field, value)


    if field == "website" then


        value =
            string.format(
                "[%s %s]",
                value,
                "وبگاه"
            )


    elseif field == "instagram" then


        value =
            string.format(
                "[%s اینستاگرام]",
                value
            )


    elseif field == "telegram" then


        value =
            string.format(
                "[%s تلگرام]",
                value
            )


    elseif field == "coordinates" then


        value =
            string.format(
                "{{مختصات|%s}}",
                value
            )


    end


    renderField(
        box,
        field,
        value
    )

end
--------------------------------------------------------------------------------
-- LAYOUT PROCESSOR
--------------------------------------------------------------------------------

local function renderLayout(box, args, layout)


    local fields =
        data.layouts[layout]


    if not fields then
        return
    end


    local hasValue = false


    for _, field in ipairs(fields) do


        local value =
            getValue(
                args,
                field
            )


        if value then

            hasValue = true

            break

        end

    end


    if not hasValue then

        return

    end


    renderSectionHeader(
        box,
        layout
    )


    for _, field in ipairs(fields) do


        local value =
            getValue(
                args,
                field
            )


        if value then


            renderSpecialField(
                box,
                field,
                value
            )


        end

    end


end


--------------------------------------------------------------------------------
-- ENTITY RENDERER
--------------------------------------------------------------------------------

local function renderEntity(box, args, entityType)


    local entity =
        getEntity(entityType)


    if not entity then

        return

    end


    for _, layout in ipairs(entity.layouts) do


        renderLayout(
            box,
            args,
            layout
        )


    end


end


--------------------------------------------------------------------------------
-- INFOBOX BUILDER
--------------------------------------------------------------------------------

local function buildInfobox(args)


    local entityType =
        detectEntity(args)


    local box =
        mw.html.create("table")


    box
        :addClass(
            INFOBOX_CLASS
        )


    renderTitle(
        box,
        entityType,
        args
    )


    renderImage(
        box,
        args
    )


    renderEntity(
        box,
        args,
        entityType
    )


    return tostring(box)

end


--------------------------------------------------------------------------------
-- MAIN FUNCTION
--------------------------------------------------------------------------------

function p.main(frame)


    local args =
        normalizeArgs(
            frame:getParent()
        )


    return buildInfobox(
        args
    )

end


--------------------------------------------------------------------------------
-- INVOKE SUPPORT
--------------------------------------------------------------------------------

function p.infobox(frame)

    return p.main(frame)

end
--------------------------------------------------------------------------------
-- TEMPLESTYLE SUPPORT
--------------------------------------------------------------------------------

local function addStyles()

    local frame =
        mw.getCurrentFrame()

    return frame:extensionTag(
        "templatestyles",
        "",
        {
            src = "الگو:جعبه اطلاعات ورزش/styles.css"
        }
    )

end

--------------------------------------------------------------------------------
-- FINAL WRAPPER
--------------------------------------------------------------------------------

local function finalize(html)

    return

        addStyles()

        .. html

end


--------------------------------------------------------------------------------
-- PUBLIC RENDER FUNCTION
--------------------------------------------------------------------------------

function p.render(frame)


    local args =
        normalizeArgs(
            frame:getParent()
        )


    local output =
        buildInfobox(
            args
        )


    return finalize(output)

end


--------------------------------------------------------------------------------
-- TEMPLATE ENTRY
--------------------------------------------------------------------------------

function p.invoke(frame)

    return p.render(frame)

end


--------------------------------------------------------------------------------
-- TEST SUPPORT
--------------------------------------------------------------------------------

function p.test(frame)

    local args = {

        name = "نمونه ورزشکار",

        entity_type = "player",

        nationality = "ایرانی",

        sport = "فوتبال",

        discipline = "فوتبال",

        position = "مهاجم",

        current_club = "باشگاه نمونه",

        birth_date = "۱۳۷۰",

        residence = "کرج"

    }


    return buildInfobox(args)

end


--------------------------------------------------------------------------------
-- RETURN MODULE
--------------------------------------------------------------------------------

return p