پرش به محتوا

پودمان:AlborzInfoBox: تفاوت میان نسخه‌ها

از ویکی البرز
جزبدون خلاصۀ ویرایش
جزبدون خلاصۀ ویرایش
خط ۲۱۲: خط ۲۱۲:
     ["کوه"] = "mountain",
     ["کوه"] = "mountain",
     ["غار"] = "cave",
     ["غار"] = "cave",
     ["پارک"] = "cave",
     ["پارک"] = "park",
     ["رودخانه"] = "river",
     ["رودخانه"] = "river",
     ["آبشار"] = "waterfall",
     ["آبشار"] = "waterfall",

نسخهٔ ‏۹ ژوئیهٔ ۲۰۲۶، ساعت ۱۰:۱۸

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

local p = {}

local data = mw.loadData('Module:AlborzInfoBox/Data/Geography')

-------------------------------------------------------
-- NORMALIZE (cached-safe)
-------------------------------------------------------
local function norm(s)
    if not s then return nil end
    s = mw.text.trim(s)
    s = mw.ustring.gsub(s, "[\u200C\u200D]", "")
    return mw.text.trim(s)
end

-------------------------------------------------------
-- ARG HANDLING (optimized)
-------------------------------------------------------
local function collectArgs(frame)
    local args = {}
    local function push(tbl)
        if not tbl then return end
        for k, v in pairs(tbl) do
            if v and v ~= "" then
                args[norm(k)] = mw.text.trim(v)
            end
        end
    end
    push(frame.args)
    push(frame:getParent() and frame:getParent().args)
    return args
end

-------------------------------------------------------
-- GET FIELD VALUE
-------------------------------------------------------
local function getValue(args, field)
    if not field then return nil end
    local names = {}
    if field.arg then table.insert(names, field.arg) end
    if field.args then
        for _, v in ipairs(field.args) do
            table.insert(names, v)
        end
    end
    for _, n in ipairs(names) do
        local v = args[norm(n)]
        if v and v ~= "" then
            return v
        end
    end
    return field.default
end

-------------------------------------------------------
-- ROW RENDERER (clean)
-------------------------------------------------------
local function addRow(root, label, value, raw)
    if not value or value == "" then return end
    local tr = root:tag("tr")
    tr:tag("th"):wikitext(label)
    local td = tr:tag("td")
    if raw then
        td:wikitext(value)
    else
        td:wikitext(mw.text.encode(value))
    end
end

-------------------------------------------------------
-- BADGE
-------------------------------------------------------
local badgeMap = {
    city = "شهر",
    village = "روستا",
    county = "شهرستان",
    district = "بخش",
    ruraldistrict = "دهستان",
    mountain = "کوه",
    cave = "غار",
    river = "رودخانه",
    waterfall = "آبشار",
    park = "پارک",
    historic = "بنای تاریخی"
}

local function addBadge(root, t)
    local label = badgeMap[t] or "مکان"
    root:tag("tr")
        :tag("td")
            :attr("colspan", "2")
            :css({
                ["text-align"] = "center",
                ["padding"] = "6px 0 8px 0"
            })
            :tag("span")
                :css({
                    display = "inline-block",
                    background = "#e8f0f8",
                    color = "#1e4b7a",
                    ["font-size"] = "87%",
                    ["font-weight"] = "bold",
                    padding = "3px 12px",
                    ["border-radius"] = "5px",
                    border = "1px solid #b0c8e0"
                })
                :wikitext(label)
end

-------------------------------------------------------
-- IMAGE (اصلاح شده نهایی)
-------------------------------------------------------
local function isSimpleFilename(s)
    if not s or s == "" then
        return false
    end
    s = mw.text.trim(s)

    return not (
        s:find("{", 1, true) or    -- الگو
        s:find("<", 1, true) or    -- HTML
        s:find("|", 1, true) or    -- pipe
        s:find("[[", 1, true)      -- لینک
    )
end

local function addImage(root, args)
    local content = args[norm("تصویر")] or args[norm("پرونده")] or args[norm("image")]
    if not content or content == "" then return end

    content = mw.text.trim(content)

    if isSimpleFilename(content) then
        -- تصویر معمولی (نام فایل)
        local filename = mw.ustring.gsub(content, "^[Ff]ile:", "")
        filename = mw.ustring.gsub(filename, "^پرونده:", "")

        root:tag("tr")
            :tag("td")
                :attr("colspan", "2")
                :css("text-align", "center")
                :css("padding", "4px 0 6px 0")
                :wikitext("[[File:" .. filename .. "|250px]]")
    else
        -- محتوای پیچیده مثل Photomontage (قبلاً expand شده)
        root:tag("tr")
            :tag("td")
                :attr("colspan", "2")
                :css("text-align", "center")
                :css("padding", "4px 0 6px 0")
                :wikitext(content)
    end
end

-------------------------------------------------------
-- CAPTION
-------------------------------------------------------
local function addCaption(root, args)
    local cap =
        args[norm("توضیح تصویر")] or
        args[norm("عنوان تصویر")] or
        args[norm("زیرنویس")]
    if not cap or cap == "" then return end
    root:tag("tr")
        :tag("td")
            :attr("colspan", "2")
            :css({
                ["text-align"] = "center",
                ["font-size"] = "90%",
                padding = "3px 0 8px 0"
            })
            :wikitext(mw.text.encode(cap))
end

-------------------------------------------------------
-- TITLE
-------------------------------------------------------
local function addTitle(root, args)
    local title =
        args[norm("نام")] or
        args[norm("نام رسمی")] or
        mw.title.getCurrentTitle().text
    root:tag("tr")
        :tag("th")
            :attr("colspan", "2")
            :css({
                ["text-align"] = "center",
                ["font-size"] = "118%",
                padding = "8px 4px"
            })
            :wikitext(mw.text.encode(title))
end

-------------------------------------------------------
-- TABLE
-------------------------------------------------------
local function newTable(typeKey)
    return mw.html.create("table")
        :addClass("infobox")
        :addClass("alborz-infobox")
        :addClass("infobox-type-" .. typeKey)
end

-------------------------------------------------------
-- TYPE NORMALIZATION
-------------------------------------------------------
local typeAliases = {
    ["شهرستان"] = "county",
    ["شهر"] = "city",
    ["روستا"] = "village",
    ["بخش"] = "district",
    ["دهستان"] = "ruraldistrict",
    ["کوه"] = "mountain",
    ["غار"] = "cave",
    ["پارک"] = "park",
    ["رودخانه"] = "river",
    ["آبشار"] = "waterfall",
    ["بنای تاریخی"] = "historic"
}

local function resolveType(t)
    t = norm(t) or "city"
    return typeAliases[t] or t
end

-------------------------------------------------------
-- RENDER ROWS
-------------------------------------------------------
local function renderRows(root, args, layout)
    for _, key in ipairs(layout) do
        local field = data.fields[key]
        if field then
            local value = getValue(args, field)
            if value and value ~= "" then
                addRow(root, field.label, value, field.raw)
            end
        end
    end
end

-------------------------------------------------------
-- MAIN RENDER
-------------------------------------------------------
local function render(args)
    if not data or not data.fields then
        return "Infobox data not found"
    end
    local typeKey = resolveType(args["نوع"])
    local internalType = (data.typeMap and data.typeMap[typeKey]) or typeKey
    local layout = (data.layouts and data.layouts[internalType]) or (data.layouts and data.layouts.city) or {}
    local root = newTable(internalType)
    addTitle(root, args)
    addBadge(root, internalType)
    addImage(root, args)
    addCaption(root, args)
    renderRows(root, args, layout)
    return tostring(root)
end

-------------------------------------------------------
-- EXPORT
-------------------------------------------------------
function p.main(frame)
    return render(collectArgs(frame))
end

return p