پرش به محتوا

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

از ویکی البرز
صفحه‌ای تازه حاوی «-------------------------------------------------------------------------------- -- Module:AlborzInfoBox -- Wiki Alborz -- Version 1.0 -------------------------------------------------------------------------------- local p = {} local data = mw.loadData('Module:AlborzInfoBox/Data/Geography') -------------------------------------------------------------------------------- -- Render ----------------------------------------------------...» ایجاد کرد
 
جزبدون خلاصۀ ویرایش
 
(۳۳ نسخهٔ میانیِ ایجادشده توسط همین کاربر نشان داده نشد)
خط ۱: خط ۱:
--------------------------------------------------------------------------------
local p = {}
-- Module:AlborzInfoBox
 
-- Wiki Alborz
------------------------------------------------------------------------
-- Version 1.0
-- 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 WIKITEXT
------------------------------------------------------------------------
 
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    = "منطقه شهری",


local p = {}
mountain      = "کوه",
cave          = "غار",
river        = "رودخانه",
waterfall    = "آبشار",
park          = "پارک",
historic      = "بنای تاریخی"
 
}
 
 
local function addBadge(root, typeKey)
 
local label = badgeMap[typeKey]
 
-- اگر نوع ناشناخته باشد
if not label then
label = "مکان"
end
 
local tr = root:tag("tr")
 
local td = tr:tag("td")
 
td
:attr("colspan", "2")
:addClass("infobox-badge-row")
 
local span = td:tag("span")
 
span
:addClass("infobox-badge")
: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")
 
if isSimpleFilename(content) then
 
local filename = content
 
filename = mw.ustring.gsub(
filename,
"^[Ff]ile:",
""
)
 
filename = mw.ustring.gsub(
filename,
"^پرونده:",
""
)
 
td:wikitext(
"[[File:" .. filename .. "|250px]]"
)
 
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
------------------------------------------------------------------------
 
local typeAliases = {
 
["شهرستان"]      = "county",
["county"]        = "county",
 
["شهر"]            = "city",
["city"]            = "city",
 
["روستا"]          = "village",
["village"]        = "village",
 
["بخش"]            = "district",
["district"]      = "district",
 
["دهستان"]        = "ruraldistrict",
["ruraldistrict"]  = "ruraldistrict",


local data = mw.loadData('Module:AlborzInfoBox/Data/Geography')
["محله"]          = "neighborhood",
["neighborhood"]  = "neighborhood",


--------------------------------------------------------------------------------
["منطقه شهری"]    = "urbanarea",
-- Render
["منطقه‌شهری"]    = "urbanarea",
--------------------------------------------------------------------------------
["منطقه شهری کرج"] = "urbanarea",
["منطقه"]          = "urbanarea",
["urbanarea"]      = "urbanarea",
["urban area"]    = "urbanarea",


local function render(args)
["کوه"]            = "mountain",
["mountain"]      = "mountain",


    local layout = data.layouts[args["نوع"] or "city"]
["غار"]            = "cave",
["cave"]           = "cave",


    if not layout then
["رودخانه"]        = "river",
        layout = data.layouts.city
["river"]          = "river",
    end


    local root = mw.html.create("table")
["آبشار"]          = "waterfall",
        :addClass("infobox")
["waterfall"]      = "waterfall",
        :addClass("alborz-infobox")


    --------------------------------------------------------------------------
["پارک"]          = "park",
    -- Title
["park"]          = "park",
    --------------------------------------------------------------------------


    local title = args["نام"]
["بنای تاریخی"]    = "historic",
["بنای‌تاریخی"]    = "historic",
["historic"]       = "historic"


    if not title or title == "" then
}
        title = mw.title.getCurrentTitle().text
    end


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


    --------------------------------------------------------------------------
------------------------------------------------------------------------
    -- Image
-- TYPE RESOLUTION
    --------------------------------------------------------------------------
------------------------------------------------------------------------


    if args["تصویر"] and args["تصویر"] ~= "" then
local function resolveType(value)


        root
-- اگر نوع مشخص نشده باشد
            :tag("tr")
if not value or value == "" then
                :tag("td")
return "city"
                    :attr("colspan","2")
end
                    :addClass("infobox-image")
                    :wikitext("[[پرونده:" ..
                        args["تصویر"] ..
                        "|250px|وسط]]")


        if args["توضیح تصویر"] and args["توضیح تصویر"] ~= "" then
value = norm(value)


            root
-- ابتدا از aliasهای ماژول استفاده می‌کنیم
                :tag("tr")
local resolved = typeAliases[value]
                    :tag("td")
                        :attr("colspan","2")
                        :addClass("infobox-caption")
                        :wikitext(args["توضیح تصویر"])


        end
if resolved then
return resolved
end


    end
-- سپس از typeMap موجود در Data
if data.typeMap then


    --------------------------------------------------------------------------
resolved = data.typeMap[value]
    -- Rows
    --------------------------------------------------------------------------
        for i = 1, #layout do


        local field = data.fields[layout[i]]
if resolved then
return resolved
end


        if field then
end


            local value
-- در نهایت خود مقدار
return value


            ------------------------------------------------------------------
end
            -- Default value
            ------------------------------------------------------------------


            if field.default then
                value = field.default
            end


            ------------------------------------------------------------------
------------------------------------------------------------------------
            -- Argument value
-- LAYOUT
            ------------------------------------------------------------------
------------------------------------------------------------------------


            if field.arg and args[field.arg] and args[field.arg] ~= "" then
local function getLayout(typeKey)
                value = args[field.arg]
            end


            ------------------------------------------------------------------
if not data or not data.layouts then
            -- Render row
return {}
            ------------------------------------------------------------------
end


            if value and value ~= "" then
return
data.layouts[typeKey]
or data.layouts.city
or {}


                local row = root:tag("tr")
end


                row
                    :tag("th")
                        :addClass("infobox-label")
                        :wikitext(field.label)


                if field.arg == "وبگاه" then
------------------------------------------------------------------------
-- RENDER ROWS
------------------------------------------------------------------------


                    row
local function renderRows(root, args, layout)
                        :tag("td")
                            :addClass("infobox-data")
                            :css("direction","ltr")
                            :css("text-align","left")
                            :wikitext(value)


                else
if not layout then
return
end


                    row
for _, key in ipairs(layout) do
                        :tag("td")
                            :addClass("infobox-data")
                            :wikitext(value)


                end
local field = data.fields[key]


            end
if field then


        end
local value = getValue(args, field)


    end
if value and value ~= "" then


    --------------------------------------------------------------------------
addRow(
    -- Categories
root,
    --------------------------------------------------------------------------
field.label,
value,
field.raw
)


    if args["رده"] and args["رده"] ~= "" then
end
        root:wikitext(args["رده"])
    end


    return tostring(root)
end
 
end


end
end


--------------------------------------------------------------------------------
-- Main
--------------------------------------------------------------------------------


function p.main(frame)
------------------------------------------------------------------------
-- MAIN RENDER
------------------------------------------------------------------------
 
local function render(args)
 
if not data then
return "Infobox data not found"
end
 
if not data.fields then
return "Infobox fields not found"
end
 
----------------------------------------------------------------
-- Resolve type
----------------------------------------------------------------
 
local requestedType =
args[norm("نوع")]
or args[norm("type")]
 
local typeKey =
resolveType(requestedType)
 
----------------------------------------------------------------
-- Data type map
----------------------------------------------------------------
 
local internalType = typeKey
 
if data.typeMap and data.typeMap[typeKey] then
internalType = data.typeMap[typeKey]
end
 
----------------------------------------------------------------
-- اطمینان از وجود layout
----------------------------------------------------------------
 
if not data.layouts[internalType] then
 
-- اگر نوع ناشناخته بود، شهر را پیش‌فرض نکنیم
-- بلکه از نوع مشخص‌شده استفاده کنیم.
-- در صورت نبود layout، از layout شهر استفاده می‌شود.
internalType = typeKey
 
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
)
 
return tostring(root)
 
end


    local args = {}


    local parent = frame:getParent()
------------------------------------------------------------------------
-- PUBLIC ENTRY POINT
------------------------------------------------------------------------


    if parent then
function p.main(frame)
        for k, v in pairs(parent.args) do
            if v and v ~= "" then
                args[k] = mw.text.trim(v)
            end
        end
    end


    for k, v in pairs(frame.args) do
local args =
        if v and v ~= "" then
collectArgs(frame)
            args[k] = mw.text.trim(v)
        end
    end


    return render(args)
return render(args)


end
end
------------------------------------------------------------------------
-- RETURN
------------------------------------------------------------------------


return p
return p

نسخهٔ کنونی تا ‏۷ اوت ۲۰۲۶، ساعت ۲۲:۵۶

توضیحات این پودمان می‌تواند در پودمان: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 WIKITEXT
------------------------------------------------------------------------

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

	local tr = root:tag("tr")

	local td = tr:tag("td")

	td
		:attr("colspan", "2")
		:addClass("infobox-badge-row")

	local span = td:tag("span")

	span
		:addClass("infobox-badge")
		: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")

	if isSimpleFilename(content) then

		local filename = content

		filename = mw.ustring.gsub(
			filename,
			"^[Ff]ile:",
			""
		)

		filename = mw.ustring.gsub(
			filename,
			"^پرونده:",
			""
		)

		td:wikitext(
			"[[File:" .. filename .. "|250px]]"
		)

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

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",
	["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

	value = norm(value)

	-- ابتدا از aliasهای ماژول استفاده می‌کنیم
	local resolved = typeAliases[value]

	if resolved then
		return resolved
	end

	-- سپس از typeMap موجود در Data
	if data.typeMap then

		resolved = data.typeMap[value]

		if resolved then
			return resolved
		end

	end

	-- در نهایت خود مقدار
	return value

end


------------------------------------------------------------------------
-- LAYOUT
------------------------------------------------------------------------

local function getLayout(typeKey)

	if not data or not data.layouts then
		return {}
	end

	return
		data.layouts[typeKey]
		or data.layouts.city
		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)

	if not data then
		return "Infobox data not found"
	end

	if not data.fields then
		return "Infobox fields not found"
	end

	----------------------------------------------------------------
	-- Resolve type
	----------------------------------------------------------------

	local requestedType =
		args[norm("نوع")]
		or args[norm("type")]

	local typeKey =
		resolveType(requestedType)

	----------------------------------------------------------------
	-- Data type map
	----------------------------------------------------------------

	local internalType = typeKey

	if data.typeMap and data.typeMap[typeKey] then
		internalType = data.typeMap[typeKey]
	end

	----------------------------------------------------------------
	-- اطمینان از وجود layout
	----------------------------------------------------------------

	if not data.layouts[internalType] then

		-- اگر نوع ناشناخته بود، شهر را پیش‌فرض نکنیم
		-- بلکه از نوع مشخص‌شده استفاده کنیم.
		-- در صورت نبود layout، از layout شهر استفاده می‌شود.
		internalType = typeKey

	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
	)

	return tostring(root)

end


------------------------------------------------------------------------
-- PUBLIC ENTRY POINT
------------------------------------------------------------------------

function p.main(frame)

	local args =
		collectArgs(frame)

	return render(args)

end


------------------------------------------------------------------------
-- RETURN
------------------------------------------------------------------------

return p