پودمان:AlborzInfoBox
ظاهر
توضیحات این پودمان میتواند در پودمان:AlborzInfoBox/توضیحات قرار گیرد.
local p = {}
------------------------------------------------------------------------
-- DATA
------------------------------------------------------------------------
local data = mw.loadData("Module:AlborzInfoBox/Data/Geography")
------------------------------------------------------------------------
-- NORMALIZE
------------------------------------------------------------------------
local function norm(value)
if value == nil then
return nil
end
value = tostring(value)
value = mw.text.trim(value)
-- حذف نیمفاصله و کاراکترهای نامرئی
value = mw.ustring.gsub(
value,
"[\u200C\u200D\uFEFF]",
""
)
-- یکسانسازی فاصلهها
value = mw.ustring.gsub(
value,
"%s+",
" "
)
-- حروف عربی → فارسی
value = mw.ustring.gsub(value, "ي", "ی")
value = mw.ustring.gsub(value, "ى", "ی")
value = mw.ustring.gsub(value, "ك", "ک")
return mw.text.trim(value)
end
------------------------------------------------------------------------
-- ARGUMENT HANDLING
------------------------------------------------------------------------
local function collectArgs(frame)
local args = {}
local function push(source)
if not source then
return
end
for key, value in pairs(source) do
if value ~= nil then
local normalizedKey =
norm(key)
local normalizedValue =
mw.text.trim(tostring(value))
if normalizedKey ~= ""
and normalizedValue ~= ""
then
args[normalizedKey] =
normalizedValue
end
end
end
end
-- آرگومانهای مستقیم invoke
push(frame.args)
-- آرگومانهای الگوی مادر
local parent =
frame:getParent()
if parent then
push(parent.args)
end
return args
end
------------------------------------------------------------------------
-- 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 _, name in ipairs(field.args) do
table.insert(names, name)
end
end
-- جستوجوی مقدار
for _, name in ipairs(names) do
local key =
norm(name)
local value =
args[key]
if value and value ~= "" then
return value
end
end
-- مقدار پیشفرض
if field.default ~= nil then
return field.default
end
return nil
end
------------------------------------------------------------------------
-- SAFE TEXT
------------------------------------------------------------------------
local function cleanText(value)
if value == nil then
return nil
end
value = tostring(value)
value = mw.text.trim(value)
if value == "" then
return nil
end
return value
end
------------------------------------------------------------------------
-- ADD ROW
------------------------------------------------------------------------
local function addRow(root, label, value, raw)
value =
cleanText(value)
if not value then
return
end
local tr =
root:tag("tr")
--------------------------------------------------------------------
-- Label
--------------------------------------------------------------------
local th =
tr:tag("th")
th
:attr("scope", "row")
:addClass("infobox-label")
:wikitext(label)
--------------------------------------------------------------------
-- Value
--------------------------------------------------------------------
local td =
tr:tag("td")
td:addClass("infobox-value")
if raw then
td:wikitext(value)
else
td:wikitext(
mw.text.encode(value)
)
end
end
------------------------------------------------------------------------
-- TYPE BADGE
------------------------------------------------------------------------
local badgeMap = {
city = "شهر",
village = "روستا",
county = "شهرستان",
district = "بخش",
ruraldistrict = "دهستان",
neighborhood = "محله",
urbanarea = "منطقه شهری",
mountain = "کوه",
cave = "غار",
river = "رودخانه",
waterfall = "آبشار",
park = "پارک",
historic = "بنای تاریخی"
}
local function addBadge(root, typeKey)
--------------------------------------------------------------------
-- نوع شناختهشده
--------------------------------------------------------------------
local label =
badgeMap[typeKey]
--------------------------------------------------------------------
-- نوع ناشناخته
--------------------------------------------------------------------
if not label then
label = "نوع نامشخص"
end
--------------------------------------------------------------------
-- Row
--------------------------------------------------------------------
local tr =
root:tag("tr")
local td =
tr:tag("td")
td
:attr("colspan", "2")
:addClass("alborz-infobox-type-row")
--------------------------------------------------------------------
-- Badge
--------------------------------------------------------------------
local span =
td:tag("span")
span
:addClass("alborz-infobox-type")
:wikitext(label)
end
------------------------------------------------------------------------
-- IMAGE
------------------------------------------------------------------------
local function isSimpleFilename(value)
if not value or value == "" then
return false
end
value =
mw.text.trim(value)
-- اگر مقدار شامل ویکیمتن یا HTML باشد
if value:find("{", 1, true)
or value:find("<", 1, true)
or value:find("|", 1, true)
or value:find("[[", 1, true)
then
return false
end
return true
end
------------------------------------------------------------------------
-- IMAGE RENDERER
------------------------------------------------------------------------
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)
local tr =
root:tag("tr")
local td =
tr:tag("td")
td
:attr("colspan", "2")
:addClass("infobox-image")
--------------------------------------------------------------------
-- Simple filename
--------------------------------------------------------------------
if isSimpleFilename(content) then
local filename =
content
filename =
mw.ustring.gsub(
filename,
"^[Ff]ile:",
""
)
filename =
mw.ustring.gsub(
filename,
"^پرونده:",
""
)
td:wikitext(
"[[File:"
.. filename
.. "|250px]]"
)
--------------------------------------------------------------------
-- Existing wikitext
--------------------------------------------------------------------
else
td:wikitext(content)
end
end
------------------------------------------------------------------------
-- IMAGE CAPTION
------------------------------------------------------------------------
local function addCaption(root, args)
local caption =
args[norm("توضیح تصویر")]
or args[norm("عنوان تصویر")]
or args[norm("زیرنویس")]
or args[norm("برچسب تصویر")]
if not caption
or caption == ""
then
return
end
local tr =
root:tag("tr")
local td =
tr:tag("td")
td
:attr("colspan", "2")
:addClass("infobox-caption")
:wikitext(
mw.text.encode(caption)
)
end
------------------------------------------------------------------------
-- TITLE
------------------------------------------------------------------------
local function getTitle(args)
return
args[norm("نامرسمی")]
or args[norm("نام رسمی")]
or args[norm("نام")]
or mw.title.getCurrentTitle().text
end
local function addTitle(root, args)
local title =
getTitle(args)
if not title
or title == ""
then
return
end
local tr =
root:tag("tr")
local th =
tr:tag("th")
th
:attr("colspan", "2")
:addClass("infobox-title")
:wikitext(
mw.text.encode(title)
)
end
------------------------------------------------------------------------
-- TABLE
------------------------------------------------------------------------
local function newTable(typeKey)
local root =
mw.html.create("table")
root
:addClass("infobox")
:addClass("alborz-infobox")
:addClass("infobox-geography")
:addClass("infobox-type-" .. typeKey)
:attr("role", "presentation")
return root
end
------------------------------------------------------------------------
-- TYPE ALIASES
------------------------------------------------------------------------
-- نکته:
-- کلیدها در این جدول باید با خروجی norm() هماهنگ باشند.
-- چون norm نیمفاصله را حذف میکند، «منطقهشهری» به «منطقهشهری»
-- تبدیل میشود.
local typeAliases = {
--------------------------------------------------------------------
-- شهرستان
--------------------------------------------------------------------
["شهرستان"] = "county",
["county"] = "county",
--------------------------------------------------------------------
-- شهر
--------------------------------------------------------------------
["شهر"] = "city",
["city"] = "city",
--------------------------------------------------------------------
-- روستا
--------------------------------------------------------------------
["روستا"] = "village",
["village"] = "village",
--------------------------------------------------------------------
-- بخش
--------------------------------------------------------------------
["بخش"] = "district",
["district"] = "district",
--------------------------------------------------------------------
-- دهستان
--------------------------------------------------------------------
["دهستان"] = "ruraldistrict",
["ruraldistrict"] = "ruraldistrict",
--------------------------------------------------------------------
-- محله
--------------------------------------------------------------------
["محله"] = "neighborhood",
["neighborhood"] = "neighborhood",
--------------------------------------------------------------------
-- منطقه شهری
--------------------------------------------------------------------
["منطقه شهری"] = "urbanarea",
["منطقهشهری"] = "urbanarea",
["منطقه شهری کرج"] = "urbanarea",
["منطقهشهری کرج"] = "urbanarea",
["منطقه"] = "urbanarea",
["urbanarea"] = "urbanarea",
["urban area"] = "urbanarea",
--------------------------------------------------------------------
-- کوه
--------------------------------------------------------------------
["کوه"] = "mountain",
["mountain"] = "mountain",
--------------------------------------------------------------------
-- غار
--------------------------------------------------------------------
["غار"] = "cave",
["cave"] = "cave",
--------------------------------------------------------------------
-- رودخانه
--------------------------------------------------------------------
["رودخانه"] = "river",
["river"] = "river",
--------------------------------------------------------------------
-- آبشار
--------------------------------------------------------------------
["آبشار"] = "waterfall",
["waterfall"] = "waterfall",
--------------------------------------------------------------------
-- پارک
--------------------------------------------------------------------
["پارک"] = "park",
["park"] = "park",
--------------------------------------------------------------------
-- بنای تاریخی
--------------------------------------------------------------------
["بنای تاریخی"] = "historic",
["بنایتاریخی"] = "historic",
["historic"] = "historic"
}
------------------------------------------------------------------------
-- TYPE RESOLUTION
------------------------------------------------------------------------
local function resolveType(value)
--------------------------------------------------------------------
-- نوع پیشفرض
--------------------------------------------------------------------
if not value
or value == ""
then
return "city"
end
--------------------------------------------------------------------
-- Normalize
--------------------------------------------------------------------
value =
norm(value)
--------------------------------------------------------------------
-- Alias داخلی
--------------------------------------------------------------------
local resolved =
typeAliases[value]
if resolved then
return resolved
end
--------------------------------------------------------------------
-- Data typeMap
--------------------------------------------------------------------
if data
and data.typeMap
then
resolved =
data.typeMap[value]
if resolved then
return resolved
end
end
--------------------------------------------------------------------
-- اگر مقدار خودش یک typeKey معتبر باشد
--------------------------------------------------------------------
if data
and data.layouts
and data.layouts[value]
then
return value
end
--------------------------------------------------------------------
-- نوع ناشناخته
--------------------------------------------------------------------
return nil
end
------------------------------------------------------------------------
-- LAYOUT
------------------------------------------------------------------------
local function getLayout(typeKey)
if not data
or not data.layouts
then
return {}
end
if not typeKey then
return {}
end
--------------------------------------------------------------------
-- فقط layout همان نوع
--------------------------------------------------------------------
return data.layouts[typeKey]
or {}
end
------------------------------------------------------------------------
-- RENDER ROWS
------------------------------------------------------------------------
local function renderRows(root, args, layout)
if not layout then
return
end
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)
--------------------------------------------------------------------
-- Data validation
--------------------------------------------------------------------
if not data then
return "Infobox data not found"
end
if not data.fields then
return "Infobox fields not found"
end
if not data.layouts then
return "Infobox layouts not found"
end
--------------------------------------------------------------------
-- Requested type
--------------------------------------------------------------------
local requestedType =
args[norm("نوع")]
or args[norm("type")]
--------------------------------------------------------------------
-- Resolve type
--------------------------------------------------------------------
local internalType =
resolveType(requestedType)
--------------------------------------------------------------------
-- اگر نوع مشخص نشده بود
--------------------------------------------------------------------
if not internalType then
-- فقط زمانی شهر به عنوان پیشفرض استفاده میشود
-- که اصلاً نوع وارد نشده باشد.
if not requestedType
or requestedType == ""
then
internalType = "city"
else
-- نوع ناشناخته را همانطور نگه میداریم
-- تا به اشتباه شهر یا مکان نمایش داده نشود.
internalType =
norm(requestedType)
end
end
--------------------------------------------------------------------
-- Data type map
--------------------------------------------------------------------
if data.typeMap
and data.typeMap[internalType]
then
internalType =
data.typeMap[internalType]
end
--------------------------------------------------------------------
-- Layout
--------------------------------------------------------------------
local layout =
getLayout(internalType)
--------------------------------------------------------------------
-- Table
--------------------------------------------------------------------
local root =
newTable(internalType)
--------------------------------------------------------------------
-- Title
--------------------------------------------------------------------
addTitle(
root,
args
)
--------------------------------------------------------------------
-- Type badge
--------------------------------------------------------------------
addBadge(
root,
internalType
)
--------------------------------------------------------------------
-- Image
--------------------------------------------------------------------
addImage(
root,
args
)
--------------------------------------------------------------------
-- Caption
--------------------------------------------------------------------
addCaption(
root,
args
)
--------------------------------------------------------------------
-- Rows
--------------------------------------------------------------------
renderRows(
root,
args,
layout
)
--------------------------------------------------------------------
-- Output
--------------------------------------------------------------------
return tostring(root)
end
------------------------------------------------------------------------
-- PUBLIC ENTRY POINT
------------------------------------------------------------------------
function p.main(frame)
local args =
collectArgs(frame)
return render(args)
end
------------------------------------------------------------------------
-- RETURN
------------------------------------------------------------------------
return p