Mô đun:Ilh

-- based on the Chinese implementation: https://zh.wikipedia.org/wiki/模块:Ilh
-- used for Vietnamese Wikipedia

-- initial section
local ilh = {}
local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")
--[[
from jirutka's implementation: https://gist.github.com/jirutka/666bccf338097b87873c447544c12424
abuse % operator for string interpolation (use a template syntax similar to JavaScript)
you can actually use this in the same way as str.format
for instance: "${hello} ${world}" % {['hello'] = "Hello", ['world'] = 'World'}
or: "%s %s" % {"Hello", "World"}
--> Hello World
--]]
function o(str)
if type(str) ~= "string" then
error("the o func only receives string!")
end
return setmetatable({str}, {
__mod = function(str, args)
str = str[1]
if type(args) ~= "table" then
args = {args}
end
return str:format(unpack(args)):gsub("($%b{})", function(placeholder)
return args[mw.text.trim(placeholder:sub(3, -2))] or placeholder
end)
end
})
end
function createOutputBuilder()
local methods = {
insert = table.insert,
join = table.concat,
}
return setmetatable({}, {
__index = function(t, key)
return methods[key]
end
});
end

-- implementating section
function ilh.main(frame)
local args = getArgs(frame, {parentFirst = true})
return ilh._ilh(args)
end

function ilh._ilh(args)
local context = {}
context.isMainPage = ilh.isMainPage()
context.localPage = args[1] -- local page's name
context.foreignPage = args[2] or args[1] -- foreign page's name
context.displayName = ilh.displayName(args)
context.langCode = args["lang-code"]
context.lang = args.lang
context.nocat = yesno(args.nocat, false) -- standardize the "nocat" field to boolean type

-- does the local page exist?
context.isExist = (args["$exist$"] and args["$exist$"] == 1) or ilh.isExist(context.localPage)

-- get current page object
local curPage_obj = mw.title.getCurrentTitle()

-- is the current page in User (2) or Module (828) namespace?
context.isNoCatWithNamespace = curPage_obj:inNamespaces(2, 828)

-- if we are at the main page, just give the link only
-- else, we return an "interlanguage link"
return (context.isMainPage and ilh.onlyLink(context)) or ilh.functionLink(context)
end

--
if the local page exists, return a link to it (use displayName as... display name),
if not, return displayName
--
function ilh.onlyLink(context)
return context.isExist and (o"${displayName}" % context) or context.displayName
end
--
create interlanguage link html
--
function ilh.functionLink(context)
-- escape double quote
context._localPage = context.localPage:gsub('"', "&quot;")
context._foreignPage = context.foreignPage:gsub('"', "&quot;")

context._blue_link_class = (context.isExist and "ilh-blue") or ""
context._alternativePage = context.foreignPage or context.localPage

-- are we allowed to use Category:Interlanguage_link_template_existing_link?
local need_cat = not (context.nocat or context.isNoCatWithNamespace)

local output_html = createOutputBuilder()
output_html:insert(
o % context)
output_html:insert()
output_html:insert(o"${displayName}" % context)
output_html:insert("")
if context.isExist then
if need_cat then
-- https://en.wikipedia.org/wiki/Category:Interlanguage_link_template_existing_link
output_html:insert("")
end
else
output_html:insert(' (')
output_html:insert( .. context.lang .. "")

output_html:insert(': ')

output_html:insert()
output_html:insert(
o'${_alternativePage}' % context
)
output_html:insert("")
output_html:insert(") ")
end
output_html:insert("")

return output_html:join("")
end
-- the implementations below use some pretty expensive methods/properties of mw module
-- maybe there will be more efficient implementations in the future
--
resolve displayName from args, return ('3' or 'd' or '1') field in args
--
function ilh.displayName(args)
return args["3"] or args["d"] or args["1"]
end

--
check if the current page is the main page
--
function ilh.isMainPage()
local mainpage_msgobj = mw.message.new("Mainpage")
mainpage_msgobj = mainpage_msgobj:inLanguage(mw.getContentLanguage():getCode())
local mainPage_obj = mw.title.makeTitle(0, mainpage_msgobj:plain())
local curpage_obj = mw.title.getCurrentTitle()
return mw.title.equals(mainPage_obj, curpage_obj)
end

--
a wrapper of ilh._isExist to handle its' potential thrown error
--
function ilh.isExist(pageName)
local execStatus, result = pcall(ilh._isExist, pageName)

if execStatus then
return result
else
return false
end
end

--
check if there is a page named
--
function ilh._isExist(pageName)
local localPage_obj = mw.title.makeTitle(0, pageName)
return localPage_obj.exists
end

return ilh