# Module:FindYDCportal

---
For a given 3- or 4-digit year or decade, find the most specific portal  
which actually exists.  
Takes one parameter, which must be either a year (e.g. "1879", "1123")  
or a decade (e.g. "1940s", "790s").  
If a portal is found, return its name without the namespace prefix  
(e.g. for "Portal:1980s" return "1980s"); otherwise return an empty string.  
If the parameter is missing, empty, or does not fit the required format,  
an empty string is returned"  

local p = {}  

-- This table of existing decade portals is the first check of whether a portal  
-- exists for a given decade.  
-- If the decade is listed in this table, then a system call is made to verify its existence  
-- This approach has two advantages:  
-- 1/ It reduces server load by reducing the number of expensive system calls  
-- 2/ It avoids creating backlinks to non-existing portals, because a each .exists check  
-- generates a backlink  
local existingDecadePortals = {  
["1920s"] = true,  
["1950s"] = true,  
["1960s"] = true,  
["1980s"] = true,  
["1990s"] = true  
}  

-- check for the existence of a portal with the given name  
-- if it exists, returns the name  
-- otherwise returns nil  
function doesPortalExist(portalName)  
local portalPage = mw.title.new( portalName, "Portal" )  
if (portalPage.exists) then  
return portalName  
end  
return nil  
end  

-- check for the existence of a portal with the name of that year  
-- if it exists, returns the year  
-- otherwise calls decadeCheck, and returns that result  
-- otherwise returns nil  
function checkYear(yearParam)  
---
the year portals have all been deleted, so comment out this section  
if doesPortalExist(yearParam) then  
return yearParam  
end  
---
-- myDecade = the year, with the last digit stripped  
-- e.g. "1694" → "1690"  
-- Note that a decade is written as usul=ally written "YYY0s"  
local myDecade = mw.ustring.gsub(yearParam, "%d$", "")  
return checkDecade(myDecade)  
end  

-- check for the existence of a portal with the name of that decade  
-- if it exists, returns the year  
-- otherwise calls decadeCheck, and returns that result  
-- otherwise returns nil  
function checkDecade(decadeParam)  
local mydecade = decadeParam .. "0s"  
if (existingDecadePortals[mydecade] == true) then  
if doesPortalExist(mydecade) then  
return mydecade  
end  
end  
-- We don't have a portal for the decade, so now try the century.  
---
the century portals have all been deleted, so comment out this section  

local myCenturyString = mw.ustring.gsub(decadeParam, "%d$", "")  
local myCenturyNum = tonumber(myCenturyString)  
local myCenturyNum = tonumber(myCenturyString)  
-- increment by one, because we have now conveted e.g. "1870s" to "18"  
-- but that's the 19th century  
myCenturyNum = myCenturyNum + 1  
-- the century portals have all been deleted, so disable the centeury checking  
-- return checkCentury(tostring(myCenturyNum))  
-- return ""  
end  

-- check for the existence of a portal with the name of that century  
-- if it exists, returns the century  
-- otherwise returns an empty string  
function checkCentury(centuryParam)  
local myCenturyString = ordinal_numbers(centuryParam) .. " நூற்றாண்டு"  
if doesPortalExist(myCenturyString) then  
return myCenturyString  
end  
return ""  
end  

-- converts a string number to an string ordinal  
-- e.g. 21 → 21st  
-- 17 → 17th  
-- code copied from https://stackoverflow.com/questions/20694133/how-to-to-add-th-or-rd-to-the-date (license:CC BY-SA 3.0 )  
function ordinal_numbers(n)  
local ordinal, digit = {"-ஆம்", "-ஆம்", "-ஆம்"}, string.sub(n, -1)  
if tonumber(digit) > 0 and tonumber(digit) <= 3 and string.sub(n,-2) ~= 11 and string.sub(n,-2) ~= 12 and string.sub(n,-2) ~= 13 then  
return n .. ordinal[tonumber(digit)]  
else  
return n .. "-ஆம்"  
end  
end  

function trim(s)  
return s:match "^%s*(.-)%s*$"  
end  

function p.findydcportal  
-- Expects one parameter  
-- } = a 3- or 4-digit year or deacde  
-- e.g. 1916  
-- 1504  
-- 1630s  
-- 920s  
local arg1 = .args[1]  
if arg1 == nil then  
return ""  
end  
arg1 = trim(arg1) -- strip leading and trailing spaces  
if (mw.ustring.match(arg1, "^%d%d%d%d?$")) then  
-- it's a 3- or 4-digit-year  
return checkYear(arg1)  
elseif (mw.ustring.match(arg1, "^%d%d%d?0s$")) then  
-- it's a 3- or 4-digit decade  
-- so strip the trailing "0s"  
local decadeArg = mw.ustring.gsub(arg1, "0s$", "")  
return checkDecade(decadeArg)  
end  
-- If we get here, then arg1 was neither a year nor a decade  
-- This is going to be a helper template, and diagnostics woud be intrusive  
-- So just return an empty string  
return ""  
end  

return p