Module:City

    From Commons

    Documentation for this module may be created at Module:City/doc

    local p = {}
    
    function p.qCode(place)
    	-- recover a q-code based on place name, also if one can link to a page on commons return such link
    	local item, link = nil, nil
    
        -- === STEP 1: if "place" is empty than return nothing ==============
    	if (not place) or (place == "") then
    		return item, link
    	end
    	
      -- === STEP 2: Check if "place"  holds a q-code or matches any of the hardwired names  ==============
    	if string.match(place, "^Q%d+$") then
    		return place, link -- place string contains a q-code
    	else
    		-- if multiple calls to {{City}} from a single file, than mw.loadData should load [[Module:City/data]] only once
    		local LookupTable = mw.loadData("Module:City/data")
    		item = LookupTable[mw.ustring.lower(place)]
    		if item then
    			return item, link
    		end
    	end
    
    	-- === STEP 3: Check if {{{1}}} matches existing template, gallery or category and if so provide the link  ===
    	if #place>=3 and #place<40 then
    		local page = mw.title.new( place, '' )
    		if page and page.exists then
    			item = mw.wikibase.getEntityIdForTitle( place )
    			link = "[[" .. place .. "]]"
    			if item then
    				return item, link
    			end
    		end
    		
    		page = mw.title.new( place, 'category' )
    		if page and page.exists then
    			item = mw.wikibase.getEntityIdForTitle( 'Category:' .. place )
    			link = "[[:Category:" .. place .. "|" .. place .. "]]"
    			if item then
    				local entity = mw.wikibase.getEntityObject(item)
    				if entity then 
    					local s = entity:getBestStatements( 'P31' )
    					if s[1] and s[1].mainsnak.datavalue.value.id=="Q4167836" then 
    						-- if "instance of "(P31) = "Wikimedia category" (Q4167836)
    						s = entity:getBestStatements( 'P301' ) -- category's main topic 
    						if s[1] then -- if property "category's main topic" (P301) is set
    							item = s[1].mainsnak.datavalue.value.id 
    						else
    							item = nil
    						end
    					end
    				end
    			end
    		end 
    	end
    	return item, link
    end
    
    function p._city(place, lang, link)
    	if (not place) or (place == "") then
    		return "" --if "place" is empty than do nothing
    	end
    	
    	if string.match(place, "[%{%{|%[%[].+[%}%}|%]%]]") then
    		return place --  if "place" already has a link and if so than skip the rest of the template
    	end
    	
        -- Check if we can recover a q-code 
    	local item, linkStr = p.qCode(place)
    	if item then
    		local wikidata = require("Module:Wikidata label")
    		return wikidata._getLabel(item, lang, link)
    	elseif linkStr then
    		return linkStr -- no q-code but we matched one of the galleries or categories
    	end
    
    	-- return as is
    	return place
    end
    
    function p.city(frame)
    	local args = frame.args
    	if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then 
    		args.lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language 
    	end
    	if (not args.link) or (mw.text.trim(args.link) == "") then
    		args.link = "wikipedia"
    	end
    	args.place = mw.text.trim(args.place or '')
    	return p._city(args.place, args.lang, args.link)
    end
    
    return p