Module:Sister project links

From faraghaib
Revision as of 12:54, November 30, 2025 by Admin (talk | contribs) (2 revisions imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

-- Module to create sister project link box local getArgs = require('Module:Arguments').getArgs local commonsLink = require('Module:Commons link') local p = {}

-- Function to canonicalize string -- search for variants of "yes", and "no", and transform -- them into a standard form (like Template:YesNo) -- Argument: -- s --- input string -- Result: -- {x,y} list of length 2 -- x = nil if s is canonicalized, otherwise has trimmed s -- y = canonical form of s (true if "yes" or other, false if "no", nil if blank) local function canonicalize(s) if s == nil then return {nil, nil} end s = mw.text.trim(tostring(s)) if s == "" then return {nil, nil} end lowerS = s:lower() -- Check for various forms of "yes" if lowerS == 'yes' or lowerS == 'y' or lowerS == 't' or lowerS == 'بله' or lowerS == '1' or lowerS == 'true' or lowerS == 'on' then return {nil, true} end

   -- Check for various forms of "no"

if lowerS == 'no' or lowerS == 'n' or lowerS == 'f' or lowerS == 'خیر' or lowerS == 'نه' or lowerS == '0' or lowerS == 'false' or lowerS == 'off'then return {nil, false} end

   -- Neither yes nor no recognized, leave string trimmed

return {s, true} end

-- Merge two or more canonicalized argument lists -- Arguments: -- argList = list of canonicalized arguments -- noAll = if true, return no when all argList is no. -- otherwise, return blank when all argList is blank local function mergeArgs(argList,noAll) local test = nil -- default, return blank if all blank if noAll then test = false -- return no if all no end local allSame = true -- Search through string for first non-no or non-blank for _, arg in ipairs(argList) do if arg[2] then return arg -- found non-no and non-blank, return it end -- test to see if argList is all blank / no allSame = allSame and (arg[2] == test) end -- if all blank / no, return blank / no if allSame then return {nil, test} -- all match no/blank, return it end -- otherwise, return no / blank if noAll then return {nil, nil} end return {nil, false} end

-- Function to get sitelink for a wiki -- Arguments: -- wiki = db name of wiki to lookup -- qid = QID of entity to search for, current page entity by default local function getSitelink(wiki,qid) qid = qid or mw.wikibase.getEntityIdForCurrentPage() qid = qid and qid:upper() -- return nil if some sort of lookup failure return qid and mw.wikibase.getSitelink(qid,wiki) end

local wdMismatch = nil local wdNamespace = nil local wdHidden = nil local defaultSearch = nil

-- Function to generate the sister link itself -- Arguments: -- args = argument table for function -- args[1] = canonicalized page to fetch -- args.default = link when blank -- args.auto = new auto mode (don't fall back to search) -- args.sitelink = wikidata sitelink (if available) -- args.sisterDbName = DB name of sister site (to get sitelink) -- args.qid = QID of entity -- args.search = fallback string to search for -- args.sisterPrefix = wikitext prefix for sister site -- args.information = type of info sister site contains -- args.sisterName = friendly human name of sister site function p._sisterLink(args) if args[1][2] == false or (not args.default and args[1][2] == nil) then return nil --- either editor specified "no", or "blank" (and default=no), then skip this sister end local sitelink = args.sitelink or (args.sisterDbName and getSitelink(args.sisterDbName,args.qid)) if args.auto and not sitelink and args[1][2] == nil then return nil --- in auto mode, if link is blank and no sitelink, then skip end -- fallback order of sister link: first specified page, then wikidata, then search local link = args[1][1] or sitelink or (args.search and "Special:"..args.search) if not link then return nil --- no link found, just skip end -- update state for tracking categories if args[1][1] and sitelink then -- transform supplied page name to be in wiki-format local page = mw.ustring.gsub(args[1][1],"_"," ") page = mw.ustring.sub(page,1,1):upper()..mw.ustring.sub(page,2) local pageNS = mw.ustring.match(page,"^([^:]+):") local sitelinkNS = mw.ustring.match(sitelink,"^([^:]+):") if page == sitelink then wdHidden = args.sisterPrefix elseif pageNS ~= sitelinkNS then wdNamespace = args.sisterPrefix else wdMismatch = args.sisterPrefix end -- if no page link, nor a wikidata entry, and search is on, then warn elseif not (args[1][2] or sitelink) and args.search then defaultSearch = args.sisterPrefix end return ""..args.information .." از "..args.sisterName end

-- Function to generate HTML for one sister link -- Arguments: -- container = parent HTML object -- args = argument table for function -- args[1] = canonicalized page to fetch -- args.default = link when blank -- args.auto = new auto mode (don't fall back to search) -- args.sitelink = wikidata sitelink (if available) -- args.sisterDbName = DB name of sister site (to get sitelink) -- args.qid = QID of entity (for debugging) -- args.search = fallback string to search for -- args.logo = filename of sister logo (no namespace) -- args.sisterPrefix = wikitext prefix for sister site -- args.information = type of info sister site contains -- args.sisterName = friendly human name of sister site local function oneSister(container,args) local link = p._sisterLink(args) if not link then return nil end local li = container and container:tag('li') or mw.html.create('li') li:css("min-height","31px") -- html element for 27px-high logo local logo = li:tag('span') logo:css("display","inline-block") logo:css("width","31px") logo:css("line-height","31px") logo:css("vertical-align","middle") logo:css("text-align","center") logo:wikitext("27x27px|middle|link=|alt=") -- html element for link local linkspan = li:tag('span') linkspan:css("display","inline-block") linkspan:css("margin-right","4px") linkspan:css("width","182px") linkspan:css("vertical-align","middle") linkspan:wikitext(link) return li end

-- Function to create html containers for sister project link list -- Arguments: -- args = table of arguments -- args.position: if 'left', position links to left -- args.collapsible: if non-empty, make box collapsible. If 'collapse', start box hidden -- args.style: CSS style string appended to end of default CSS -- args.display: boldface name to display local function createContainer(args) -- Outermost div (css from previous version of Template:Project sister links) local container = mw.html.create('div') container:attr("role","navigation") container:attr("aria-labelledby","sister-projects") container:addClass("metadata") container:addClass("plainlinks") container:addClass("sistersitebox") container:addClass("plainlist") if args.position and args.position:lower() == "right" or args.position == "راست" then container:addClass("mbox-small-right") else container:addClass("mbox-small") end if args.collapsible then container:addClass("mw-collapsible") if args.collapsible == "collapsed" then container:addClass("mw-collapsed") end end container:css("border","1px solid #aaa") container:css("padding",0) container:css("background","#f9f9f9") container:cssText(args.style) -- Div for text header local header = container:tag('div') header:css("clear",args.collapsible and "both") header:css("padding","0.75em 0") header:css("text-align","center") -- pagename in bold as part of header local pagename = header:tag('b') pagename:css("display","block") pagename:wikitext(args.display or args[1]) local headerText = "در " headerText = headerText..'پروژه‌های خواهر ویکی‌پدیا' header:wikitext(headerText) -- start the unordered list element here local ul = container:tag('ul') ul:addClass(args.collapsible and "mw-collapsible-content") ul:css("border-top","1px solid #aaa") ul:css("padding","0.75em 0") ul:css("width","217px") ul:css("margin","0 auto") -- pass ul element back to main, so sister links can be added return ul end

function p._main(args) local titleObject = mw.title.getCurrentTitle() -- Default title/search string is PAGENAME args[1] = args[1] or titleObject.text -- Persian Wikipedia specific arguments translator if args["فراویکی"] then args["m"] = args["فراویکی"] end if args["مدیاویکی"] then args["mw"] = args["مدیاویکی"] end if args["ویکی‌انبار"] then args["commons"] = args["ویکی‌انبار"] end if args["رده_انبار"] then args["commonscat"] = args["رده_انبار"] end if args["ویکی‌داده"] then args["d"] = args["ویکی‌داده"] end if args["ویکی‌دانشگاه"] then args["v"] = args["ویکی‌دانشگاه"] end if args["ویکی‌خبر"] then args["n"] = args["ویکی‌خبر"] end if args["ویکی‌سفر"] then args["voy"] = args["ویکی‌سفر"] end if args["ویکی‌کتاب"] then args["b"] = args["ویکی‌کتاب"] end if args["ویکی‌نسک"] then args["b"] = args["ویکی‌نسک"] end if args["ویکی‌گفتاورد"] then args["q"] = args["ویکی‌گفتاورد"] end if args["ویکی‌گونه"] then args["species"] = args["ویکی‌گونه"] end if args["گونه"] then args["species"] = args["گونه"] end if args["نویسنده_گونه"] then args["species_author"] = args["نویسنده_گونه"] end if args["ویکی‌نبشته"] then args["s"] = args["ویکی‌نبشته"] end if args["نویسنده"] then args["author"] = args["نویسنده"] end if args["ویکی‌واژه"] then args["wikt"] = args["ویکی‌واژه"] end -- Box styling and other parameters if args["جمع‌شونده"] then args["collapsible"] = args["جمع‌شونده"] end if args["خودکار"] then args["auto"] = args["خودکار"] end if args["سبک"] then args["style"] = args["سبک"] end if args["موقعیت"] then args["position"] = args["موقعیت"] end if args["نمایش"] then args["display"] = args["نمایش"] end

-- Canonicalize all sister links (handle yes/no/empty) for _, k in pairs({"wikt","c","commons","n","q","s","b","voy", "v","d","species","species_author","m","mw"}) do args[k] = canonicalize(args[k])

   end
   -- Canonicalize general parameters
   for _,k in pairs({"auto","commonscat","author"}) do
   	args[k] = canonicalize(args[k])[2]
   end
   -- Fill in args.qid with current qid (if available)
   args.qid = args.qid or mw.wikibase.getEntityIdForCurrentPage()

args.qid = args.qid and args.qid:upper() -- Initialize tracking categories to "no track"

   wdMismatch = nil
   wdNamespace = nil
   wdHidden = nil
   defaultSearch = nil

local ul = createContainer(args) -- WIKTIONARY oneSister(ul,{args.wikt,auto=args.auto,qid=args.qid,default=true, logo="Wiktionary-logo-v2.svg",sisterPrefix="wikt", search="Search/"..args[1],information="در میان واژه‌ها", sisterName="ویکی‌واژه",sisterDbName="fawiktionary"})

   -- COMMONS
   --     use Module:Commons link to determine best commons link

local cLink = (not args.commonscat) and commonsLink._hasGallery(args.qid) or commonsLink._hasCategory(args.qid) local commonsPage = mergeArgs({args.c,args.commons}) if commonsPage[1] and not mw.ustring.match(commonsPage[1]:lower(),"^category:") then commonsPage[1] = (args.commonscat and "Category:" or "")..commonsPage[1] end local commonsSearch = "Search/"..(args.commonscat and "Category:" or "")..args[1] oneSister(ul,{commonsPage,auto=args.auto,qid=args.qid, default=true,sitelink=cLink,logo="Commons-logo.svg", sisterPrefix="c",search=commonsSearch,information="در میان تصاویر و رسانه‌ها", sisterName="ویکی‌انبار"}) -- WIKINEWS oneSister(ul,{args.n,auto=args.auto,qid=args.qid,default=true, logo="Wikinews-logo.svg",sisterPrefix="n",search="Search/"..args[1], information="در میان خبرها",sisterName="ویکی‌خبر",sisterDbName="fawikinews"}) -- WIKIQUOTE oneSister(ul,{args.q,auto=args.auto,qid=args.qid,default=true, logo="Wikiquote-logo.svg",sisterPrefix="q",search="Search/"..args[1], information="در میان گفتاوردها",sisterName="ویکی‌گفتاورد",sisterDbName="fawikiquote"}) -- WIKISOURCE if args.author and args.s[1] then args.s[1] = "پدیدآورنده:"..args.s[1] end oneSister(ul,{args.s,auto=args.auto,qid=args.qid,default=true, logo="Wikisource-logo.svg",sisterPrefix="s",search="Search/"..args[1], information="در میان متون",sisterName="ویکی‌نبشته",sisterDbName="fawikisource"}) -- WIKIBOOKS oneSister(ul,{args.b,auto=args.auto,qid=args.qid,default=true, logo="Wikibooks-logo.svg",sisterPrefix="b",search="Search/"..args[1], information="در میان کتاب‌ها",sisterName="ویکی‌کتاب",sisterDbName="fawikibooks"})

   -- WIKIVOYAGE
   -- Information="guide" when we can be assured that search cannot be called
   local voyInfo = (args.voy[1] or args.voy[2] == nil) and "راهنماهای" or "اطلاعات"
   oneSister(ul,{args.voy,auto=args.auto,qid=args.qid,default=args.auto,
   	             logo="Wikivoyage-Logo-v3-icon.svg",sisterPrefix="voy",search="Search/"..args[1],
   	             information="در میان "..voyInfo.." سفر",sisterName="ویکی‌سفر",sisterDbName="fawikivoyage"})
   -- WIKIVERSITY
   oneSister(ul,{args.v,auto=args.auto,qid=args.qid,default=true,
   	             logo="Wikiversity logo 2017.svg",sisterPrefix="v",search="Search/"..args[1],
   	             information="در میان مراجع",sisterName="ویکی‌دانشگاه",sisterDbName="enwikiversity"})
   -- WIKIDATA
   oneSister(ul,{args.d,qid=args.qid,default=false,logo="Wikidata-logo.svg",sisterPrefix="d",
   	             sitelink=args.qid,search="ItemByTitle/fawiki/"..args[1],information="در میان داده‌ها",sisterName="ویکی‌داده"})
   -- WIKISPECIES
   oneSister(ul,{mergeArgs({args.species,args.species_author},1),auto=args.auto,
   	             qid=args.qid,default=args.auto,logo="Wikispecies-logo.svg",
   	             sisterPrefix="species",search="Search/"..args[1],
   	             information=(args.species[2] and "در میان گونه‌ها")
   	                          or (args.species_author[2] and "پدیدآورنده گونه") 
   	                          or "در میان گونه‌ها",
   	             sisterName="ویکی‌گونه",sisterDbName="specieswiki"})
   if args.species[2] and args.species_author[1] then 
   	-- If species_author is explicitly defined, and species is used, then make second row
   	oneSister(ul,{args.species_author,auto=args.auto,qid=args.qid,
   		             default=args.auto,logo="Wikispecies-logo.svg",
   	                 sisterPrefix="species",search="Search/"..args[1],
   	                 information="پدیدآورنده گونه",sisterName="ویکی‌گونه"})
   end
   -- META
   oneSister(ul,{args.m,qid=args.qid,default=false,logo="Wikimedia Community Logo.svg",
   	             sisterPrefix="m",search="Search/"..args[1],information="در میان گفتگوها",sisterName="فراویکی"})
   -- MEDIAWIKI
   oneSister(ul,{args.mw,qid=args.qid,default=false,logo="MediaWiki-2020-icon.svg",
   	             sisterPrefix="mw",search="Search/"..args[1],information="در میان مستندات",sisterName="مدیاویکی"})

local container = ul:allDone() -- Append tracking categories to container div -- Alpha ordering is by sister prefix if titleObject.namespace == 0 then local trackingCats = wdMismatch and ""..wdMismatch.."" or "" trackingCats = trackingCats..(wdNamespace and ""..wdNamespace.."" or "") trackingCats = trackingCats..(wdHidden and ""..wdHidden.."" or "") trackingCats = trackingCats..(defaultSearch and ""..defaultSearch.."" or "") container:wikitext(trackingCats) end return container end

-- Main entry point for generating sister project links box function p.main(frame) local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) return tostring(p._main(args)) end

-- Entry point for generating one sister link function p.link(frame) local args = getArgs(frame,{frameOnly=false,parentOnly=false,parentFirst=false}) args[1] = canonicalize(args[1]) args.auto = canonicalize(args.auto)[2] return p._sisterLink(args) end

return p