Module:Commons link
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This Lua module is used on approximately 287,000 pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
![]() | This module depends on the following other modules: |
For testing the sandbox, see Module:Commons link/sandbox/testcases.
Usage
{{#invoke:Commons link|getGallery}}
- Use wikidata to find Commons gallery corresponding to this article. If unable to find gallery in wikidata, default to searching for PAGENAME in Commons.
{{#invoke:Commons link|getGallery|title|linktext=text}}
- Link to Commons gallery at
title
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getGallery|search=string|linktext=text}}
- Link to Commons search for
string
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getCategory|fallback=string|linktext=text}}
- Use wikidata first, then if failure, use Commons search for
string
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getCategory}}
- Use wikidata to find Commons category corresponding to this article. If unable to find category in wikidata, default to searching for Category:PAGENAME in Commons.
{{#invoke:Commons link|getCategory|title|linktext=text}}
- Link to Commons category at
Category:title
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getCategory|search=string|linktext=text}}
- Link to Commons search for
Category:string
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getCategory|fallback=string|linktext=text}}
- Use wikidata first, then if failure, use Commons search for
Category:string
. Optionally, usetext
as displayed link text.
{{#invoke:Commons link|getGalleryOrCategory}}
- Use wikidata to find "best" single Commons link: try gallery first, fall back to category. Other arguments as above.
{{#invoke:Commons link|getGalleryAndCategory}}
- Lua to implement {{commons and category}}: return Commons gallery, Commons category, or both (if both found)
{{#invoke:Commons link|getGalleryAndCategory|GalleryName|CategoryName}}
- Either GalleryName or CategoryName or both can be supplied, will override wikidata search
{{#invoke:Commons link|bold=1|italic=1|nowrap=1|lcfirst=1}}
- Format of first link can be specified (any combination of bold, italic, nowrap, and lower-case first character)
{{#invoke:Commons link|linktext=link|categoryText=category}}
- Text in the first link, and the second (category) link can be overridden, also.
{{#invoke:Commons link|tracking=1}}
- Module can generate tracking categories for mismatch between supplied arguments and Wikidata.
require('strict')-- Module to find commons galleries and categories based on wikidata entrieslocalgetArgs=require('Module:Arguments').getArgslocalp={}-- Check if string is a valid QID-- Argument: QID to check-- Returns: valid (bool)localfunction_validQID(qid)returnqidandmw.ustring.find(qid,"^[Qq]%d+$")end-- Check if string is a valid wikidata property string-- Argument: property string to check-- Returns: valid (bool)localfunction_validProp(prop)returnpropandmw.ustring.find(prop,"^[Pp]%d+$")endlocalfunction_lcfirst(s)returnmw.ustring.lower(mw.ustring.sub(s,1,1))..mw.ustring.sub(s,2)end-- Format displayed linktext-- Arguments:-- s = string to display-- formatting = formatting table:-- formatting.linktext = if defined, override s-- formatting.lcfirst = lower case the first letter in display-- formatting.bold = whether to bold the display-- formatting.italic = whether to italicize the display-- formatting.nowrap = set nowrapping-- Returns:-- formatted stringlocalfunction_formatResult(s,formatting)localresultVal=formatting.linktextorsifformatting.lcfirstthenresultVal=_lcfirst(resultVal)endlocalstyle=""ifformatting.italicthenstyle="font-style:italic; "endifformatting.boldthenstyle=style.."font-weight:bold; "endifformatting.nowrapthenstyle=style.."white-space:nowrap; "endifstyle~=""thenresultVal='<span style="'..mw.text.trim(style)..'">'..resultVal..'</span>'endreturnresultValend-- Get title, namespace, and QID for current page-- Arguments:-- qid = testing only: get title of alternative page with QID=qid-- nsQid = whether to return the ns of the qid page or current-- Returns:-- title, namespace (string), qid of current page (or test page)localfunction_getTitleQID(qid,nsQid)localtitleObject=mw.title.getCurrentTitle()-- look up qid for current page (if not testing)localnsText=string.gsub(titleObject.nsText,"_"," ")-- [[phab:T369784]]ifnot_validQID(qid)thenqid=mw.wikibase.getEntityIdForCurrentPage()returntitleObject.text,nsText,qidend-- testing-only path: given a qid, determine title-- always use namespace from current page (to suppress tracking cat)qid=qid:upper()localtitle=mw.wikibase.getSitelink(qid)or""-- strip any namespace from sitelinklocalfirstColon=mw.ustring.find(title,':',1,true)localqidNsText=""iffirstColonthenqidNsText=mw.ustring.sub(title,1,firstColon-1)title=mw.ustring.sub(title,firstColon+1)endifnsQidthenreturntitle,qidNsText,qidendreturntitle,nsText,qidend-- Lookup Commons gallery in Wikidata-- Arguments:-- qid = QID of current article-- fetch = whether to lookup Commons sitelink (bool)-- commonsSitelink = default value for Commons sitelink-- Returns:-- categoryLink = name of Commons category, nil if nothing is found-- consistent = multiple wikidata fields are examined: are they consistent?-- commonsSitelink = commons sitelink for current articlelocalfunction_lookupGallery(qid,fetch,commonsSitelink)ifnot_validQID(qid)thenreturnnil,true,nilendqid=qid:upper()localgalleryLink=nillocalconsistent=true-- look up commons sitelink for article, use if not categoryiffetchthencommonsSitelink=mw.wikibase.getSitelink(qid,"commonswiki")orcommonsSitelinkendifcommonsSitelinkandmw.ustring.sub(commonsSitelink,1,9)~="Category:"thengalleryLink=commonsSitelinkend-- P935 is the "commons gallery" property for this articlelocalP935=mw.wikibase.getBestStatements(qid,"P935")[1]ifP935andP935.mainsnak.datavaluethenlocalgallery=P935.mainsnak.datavalue.valueifgalleryLinkandgalleryLink~=gallerythenconsistent=falseelsegalleryLink=galleryendendreturngalleryLink,consistent,commonsSitelinkend-- Find fallback category by looking up Commons sitelink of different page-- Arguments:-- qid = QID for current article-- property = property that refers to other article whose sitelink to return-- Returns: either category-stripped name of article, or nillocalfunction_lookupFallback(qid,property)ifnot_validQID(qid)ornot_validProp(property)thenreturnnilendqid=qid:upper()property=property:upper()-- If property exists on current article, get value (other article qid)localvalue=mw.wikibase.getBestStatements(qid,property)[1]ifvalueandvalue.mainsnak.datavalueandvalue.mainsnak.datavalue.value.idthen-- Look up Commons sitelink of other articlelocalsitelink=mw.wikibase.getSitelink(value.mainsnak.datavalue.value.id,"commonswiki")-- Check to see if it starts with "Category:". If so, strip it and returnifsitelinkandmw.ustring.sub(sitelink,1,9)=="Category:"thenreturnmw.ustring.sub(sitelink,10)endendreturnnilend-- Find Commons category by looking in wikidata-- Arguments:-- qid = QID of current article-- fetch = whether to lookup Commons sitelink (bool)-- commonsSitelink = default value for Commons sitelink-- Returns:-- categoryLink = name of Commons category, nil if nothing is found-- consistent = multiple wikidata fields are examined: are they consistent?-- commonsSitelink = commons sitelink for current articlelocalfunction_lookupCategory(qid,fetch,commonsSitelink)ifnot_validQID(qid)thenreturnnil,true,nilendqid=qid:upper()localcategoryLink=nillocalconsistent=true-- look up commons sitelink for article, use if starts with "Category:"iffetchthencommonsSitelink=mw.wikibase.getSitelink(qid,"commonswiki")orcommonsSitelinkendifcommonsSitelinkandmw.ustring.sub(commonsSitelink,1,9)=="Category:"thencategoryLink=mw.ustring.sub(commonsSitelink,10)end-- P910 is the "topic's main category". Look for commons sitelink therelocalfallback=_lookupFallback(qid,"P910")iffallbackthenifcategoryLinkandcategoryLink~=fallbackthenconsistent=falseqid=nilelsecategoryLink=fallbackendend-- P1754 is the "list's main category". Look for commons sitelink therefallback=_lookupFallback(qid,"P1754")iffallbackthenifcategoryLinkandcategoryLink~=fallbackthenconsistent=falseqid=nilelsecategoryLink=fallbackendend-- P373 is the "commons category" property for this article. This is-- a low-quality field, so should only be used as a last resort.ifcategoryLink==niland_validQID(qid)thenlocalP373=mw.wikibase.getBestStatements(qid,"P373")[1]ifP373andP373.mainsnak.datavaluethencategoryLink=P373.mainsnak.datavalue.valueconsistent=true-- P373 is never used if anything else is availableendendreturncategoryLink,consistent,commonsSitelinkend-- Does the article have a Commons gallery, and is it consistent?-- Arguments:-- qid = QID to lookup in wikidata (for testing only)-- Returns:-- filename at Commons, bool: is wikidata consistent for this article?functionp._hasGalleryConsistent(qid)localwp_title,wp_nswp_title,wp_ns,qid=_getTitleQID(qid)return_lookupGallery(qid,true)end-- Does the article have a corresponding Commons gallery?-- Arguments:-- qid = QID to lookup in wikidata (for testing only)-- Returns:-- filename at Commons if so, false if notfunctionp._hasGallery(qid)localgalleryLink,consistent=p._hasGalleryConsistent(qid)returnconsistentandgalleryLinkend-- Does the article have a Commons category? Is wikidata consistent for that?-- Arguments:-- qid = QID to lookup in wikidata (for testing only)-- prefix = whether to add "Category:" to return string (default true)-- Returns:-- filename at Commons, bool: consistentfunctionp._hasCategoryConsistent(qid,prefix)ifprefix==nilthenprefix=trueendlocalwp_title,wp_nswp_title,wp_ns,qid=_getTitleQID(qid)localcategoryLink,consistent=_lookupCategory(qid,true)ifcategoryLinkandprefixthencategoryLink="Category:"..categoryLinkendreturncategoryLink,consistentend-- Does the article have a corresponding Commons category?-- Arguments:-- qid = QID to lookup in wikidata (for testing only)-- prefix = whether to add "Category:" to return string (default true)-- Returns:-- filename at Commons if so, blank if notfunctionp._hasCategory(qid,prefix)localcategoryLink,consistent=p._hasCategoryConsistent(qid,prefix)returnconsistentandcategoryLinkend-- Create Commons link corresponding to current article-- Arguments:-- namespace = namespace in Commons ("" for galleries)-- default = use as Commons link, don't access wikidata-- search = string to search for-- fallback = string to search for if wikidata fails-- formatting = formatting parameters-- qid = QID to lookup in wikidata (for testing only)-- Returns:-- formatted wikilink to Commons in specified namespacefunctionp._getCommons(namespace,default,search,fallback,formatting,qid)localnsColonifnotnamespaceornamespace==""thennsColon=""elsensColon=namespace..":"endifdefaultthenreturn"[[Commons:"..nsColon..default.."|".._formatResult(default,formatting).."]]"endifsearchthenreturn"[[Commons:Special:Search/"..nsColon..search.."|".._formatResult(search,formatting).."]]"endlocalwp_title,wp_nswp_title,wp_ns,qid=_getTitleQID(qid)localcommonsLink=nillocalconsistent=trueifnsColon==""thencommonsLink,consistent=_lookupGallery(qid,true)elseifnamespace:lower()=="category"thencommonsLink,consistent=_lookupCategory(qid,true)end-- use wikidata if consistentifcommonsLinkandconsistentthenreturn"[[Commons:"..nsColon..commonsLink.."|".._formatResult(commonsLink,formatting).."]]"end-- if not consistent, fall back to search and add to tracking cat-- construct default result (which searches for title)localsearchResult="[[Commons:Special:Search/"..nsColon..(fallbackorwp_title).."|".._formatResult(fallbackorwp_title,formatting).."]]"ifnotconsistentandwp_ns==""thenlocalfriendlyNSifnsColon==""thenfriendlyNS="gallery"elsefriendlyNS=namespace:lower()endsearchResult=searchResult.."[[Category:Inconsistent wikidata for Commons "..friendlyNS.."]]"endreturnsearchResultend-- Returns "best" Commons link: first look for gallery, then try category-- Arguments:-- default = use as Commons link, don't access wikidata-- search = string to search for-- fallback = string to search for if wikidata lookup fails-- formatting = formatting parameters-- qid = QID to lookup in wikidata (for testing only)-- Returns:-- formatted wikilink to Commons "best" landing pagefunctionp._getGalleryOrCategory(default,search,fallback,formatting,qid)ifdefaultthenreturn"[[Commons:"..default.."|".._formatResult(default,formatting).."]]"endifsearchthenreturn"[[Commons:Special:Search/"..search.."|".._formatResult(search,formatting).."]]"endlocalwp_title,wp_nswp_title,wp_ns,qid=_getTitleQID(qid)localtrackingCats=""localgalleryLink,consistent,commonsSitelink=_lookupGallery(qid,true)-- use wikidata if either sitelink or P935 exist, and they both agreeifgalleryLinkandconsistentthenreturn"[[Commons:"..galleryLink.."|".._formatResult(galleryLink,formatting).."]]"endifnotconsistentandwp_ns==""thentrackingCats="[[Category:Inconsistent wikidata for Commons gallery]]"end-- if gallery is not good, fall back looking for categorylocalcategoryLinkcategoryLink,consistent=_lookupCategory(qid,false,commonsSitelink)ifcategoryLinkandconsistentthenreturn"[[Commons:Category:"..categoryLink.."|".._formatResult(categoryLink,formatting).."]]"..trackingCatsendifnotconsistentandwp_ns==""thentrackingCats=trackingCats.."[[Category:Inconsistent wikidata for Commons category]]"end-- return search result looking for title as last attemptreturn"[[Commons:Special:Search/"..(fallbackorwp_title).."|".._formatResult(fallbackorwp_title,formatting).."]]"..trackingCatsend-- Return link(s) Commons gallery, or category, or both from wikidata-- Arguments:-- defaultGallery = default gallery link to use, instead of wikidata-- defaultCategory = default category link to use, instead of wikidata-- categoryText = if both gallery and category, text to use in category link ("category" by default)-- oneSearch = only emit one search result-- formatting = formatting parameters-- qid = qid of page to lookup in wikidata (testing only)functionp._getGalleryAndCategory(defaultGallery,defaultCategory,categoryText,oneSearch,formatting,qid)localwp_title,wp_nswp_title,wp_ns,qid=_getTitleQID(qid)categoryText=categoryTextor"category"localtrackingCats=""localgalleryLink,galleryConsistentlocalcommonsSitelink=nilifdefaultGallerythengalleryLink=defaultGallerygalleryConsistent=trueelsegalleryLink,galleryConsistent,commonsSitelink=_lookupGallery(qid,true)endlocalgalleryGood=galleryLinkandgalleryConsistentifnotgalleryConsistentandwp_ns==""thentrackingCats="[[Category:Inconsistent wikidata for Commons gallery]]"endlocalcategoryLink,categoryConsistentifdefaultCategorythencategoryLink=defaultCategorycategoryConsistent=trueelsecategoryLink,categoryConsistent=_lookupCategory(qid,defaultGallery,commonsSitelink)endlocalcategoryGood=categoryLinkandcategoryConsistentifnotcategoryConsistentandwp_ns==""thentrackingCats=trackingCats.."[[Category:Inconsistent wikidata for Commons category]]"endlocalfirstLink-- construct default result (which searches for title)localsearchResult="[[Commons:Special:Search/"..wp_title.."|".._formatResult(wp_title,formatting).."]]"ifnotoneSearchthensearchResult=searchResult.." ([[Commons:Special:Search/Category:"..wp_title.."|"..categoryText.."]])"endlocallinkText=nilifgalleryGoodthenfirstLink=galleryLinklinkText=galleryLinkelseifcategoryGoodthenfirstLink="Category:"..categoryLinklinkText=categoryLinkelsereturnsearchResult..trackingCatsendlocalresultVal="[[Commons:"..firstLink.."|".._formatResult(linkText,formatting).."]]"ifgalleryGoodandcategoryGoodthenresultVal=resultVal.." ([[Commons:Category:"..categoryLink.."|"..categoryText.."]])"endreturnresultVal..trackingCatsend-- Compare two titles with their namespaces strippedlocalfunctiontitleMatch(s1,s2)s1=s1or""s2=s2or""s1=mw.ustring.gsub(s1,"^[^:]+:","")s2=mw.ustring.gsub(s2,"^[^:]+:","")returns1==s2endlocalgalleryTrackingCats={commons_link_on_wikidata='[[Category:Commons link is on Wikidata]]',commons_link_defined_as_pagename='[[Category:Commons link is defined as the pagename]]',commons_link_locally_defined='[[Category:Commons link is locally defined]]',commons_link_from_wikidata='[[Category:Commons link from Wikidata]]',commons_link_is_pagename='[[Category:Commons link is the pagename]]',inconsistent='[[Category:Inconsistent wikidata for Commons gallery]]'}localcategoryTrackingCats={commons_link_on_wikidata='[[Category:Commons category link is on Wikidata]]',commons_link_defined_as_pagename='[[Category:Commons category link is defined as the pagename]]',commons_link_locally_defined='[[Category:Commons category link is locally defined]]',commons_link_from_wikidata='[[Category:Commons category link from Wikidata]]',commons_link_is_pagename='[[Category:Commons category link is the pagename]]',inconsistent='[[Category:Inconsistent wikidata for Commons category]]'}localfunctionselectTrackingCat(trackingCats,wikidata,consistent,default,title)ifnotconsistentthenreturntrackingCats.inconsistentendifdefaultthen-- construct warning messageifdefault==wikidatathenreturntrackingCats.commons_link_on_wikidataendlocalwarning=""ifwikidatathenlocalgenerateWarning=require('Module:If preview')._warningwarning=generateWarning({"Commons link does not match Wikidata – [[Template:Commons_category#Resolving_discrepancies|please check]]"})endiftitleMatch(default,title)thenreturntrackingCats.commons_link_defined_as_pagename..warningendreturntrackingCats.commons_link_locally_defined..warningendifwikidatathenreturntrackingCats.commons_link_from_wikidataendreturntrackingCats.commons_link_is_pagenameend-- Figure out tracking categories and editor warnings-- Arguments:-- default = Commons link argument passed to template-- fetchGallery = whether to fetch a gallery from Wikidata-- fetchCategory = whether to fetch a category from Wikidata-- qid = force a qid for testing-- Returns:-- tracking category and possible user warning---- Note: the logic for the tracking is quite different than the logic-- for generating Commons links (above). Thus, it is separated into another-- function for code clarity and maintainability. This should not seriously -- affect performance: server time is dominated by fetching wikidata entities,-- and those entities should be cached and shared between the Commons generating-- code and this tracking code.functionp._tracking(default,fetchGallery,fetchCategory,qid)localtitle,wp_ns,wp_qid=_getTitleQID(qid,true)ifwp_ns~=""thentitle=wp_ns..":"..titleend-- only track if test or namespace=article or namespace=categoryifnot(qidorwp_ns==""orwp_ns=="Category")thenreturn""end-- determine title and namespace of wikidata and wp articlelocalwikidata=nillocalconsistent=nil-- Tracking code works for all 4 cases of states of fetchGallery/Category-- fetchGallery takes precedenceiffetchGallerythenwikidata,consistent=p._hasGalleryConsistent(qid)ifdefaultornotfetchCategoryor(consistentandwikidata)thenreturnselectTrackingCat(galleryTrackingCats,wikidata,consistent,default,title)endendiffetchCategorythenlocalcat_wikidata,cat_consistent=p._hasCategoryConsistent(qid,true)ifnotfetchGalleryor(cat_consistentandcat_wikidata)thenreturnselectTrackingCat(categoryTrackingCats,cat_wikidata,cat_consistent,default,title)endreturnselectTrackingCat(galleryTrackingCats,wikidata,consistent,default,title)endreturn""-- nothing fetched, nothing trackedendlocalfunction_createFormatting(args)localformatting={}formatting.linktext=args.linktextlocalyesNo=require('Module:Yesno')formatting.lcfirst=yesNo(args.lcfirst)formatting.bold=yesNo(args.bold)formatting.italic=yesNo(args.italic)formatting.nowrap=yesNo(args.nowrap)returnformattingend-- Testing-only entry point for _getTitleQIDfunctionp.getTitleQID(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})localtext,ns,qid=_getTitleQID(args[1],args[2])returntext..","..ns..","..(qidor"nil")end-- Testing-only entry point for _lookupFallbackfunctionp.lookupFallback(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})localfallback=_lookupFallback(args[1],args[2])returnfallbackor"nil"end-- Find the Commons gallery page associated with articlefunctionp.getGallery(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._getCommons("",args[1],args.search,args.fallback,_createFormatting(args),args.qid)end-- Find the Commons category page associated with articlefunctionp.getCategory(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})localretval=p._getCommons("Category",args[1],args.search,args.fallback,_createFormatting(args),args.qid)ifargs.trackingthenlocaldefault=nilifargs[1]thendefault="Category:"..args[1]endretval=retval..p._tracking(default,false,true,args.qid)endreturnretvalendfunctionp.getGalleryOrCategory(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})localretval=p._getGalleryOrCategory(args[1],args.search,args.fallback,_createFormatting(args),args.qid)ifargs.trackingthenretval=retval..p._tracking(args[1],true,true,args.qid)endreturnretvalendfunctionp.hasGallery(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._hasGallery(args.qid)or""endfunctionp.hasCategory(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._hasCategory(args.qid)or""endfunctionp.hasGalleryOrCategory(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._hasGallery(args.qid)orp._hasCategory(args.qid)or""endfunctionp.getGalleryAndCategory(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._getGalleryAndCategory(args[1],args[2],args.categoryText,args.oneSearch,_createFormatting(args),args.qid)endfunctionp.tracking(frame)localargs=getArgs(frame,{frameOnly=true,parentOnly=false,parentFirst=false})returnp._tracking(args[1],args.fetchGallery,args.fetchCategory,args.qid)endreturnp