Jump to content
Wikipedia The Free Encyclopedia

Module:Attached KML

From Wikipedia, the free encyclopedia
Module documentation[view] [edit] [history] [purge]
Warning This Lua module is used on approximately 14,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them.
Beta This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected.
[画像:Protected] 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 module depends on the following other modules:

Usage

On English Wikipedia, this module is called by {{Attached KML}}. See that template's documentation for usage instructions

Set up on another wiki

  1. Create template and module
    • Import this module to that wiki (or copy the code over, giving attribution in the edit summary). Give the module a name that makes sense in that wiki's language (hereafter referred to as MODULENAME)
    • Create a template (which should probably have the same name as the module, but referred to here as TEMPLATENAME) containing the code <includeonly>{{#invoke:MODULENAME|main}}</includeonly><noinclude>{{TEMPLATENAME|demo=yes}}{{Documentation}}</noinclude>
    • On Wikidata, add the template to d:Q6690822 and the module to d:Q26689774
  2. Localise the module. Edit the top bits of the module, between the comments -- ##### Localisation (L10n) settings ##### and -- #### End of L10n settings ####, replacing values between " " symbols with local values (as necessary)
  3. Create the categories defined in the module localisation. These should be made hidden categories, either by including a Template:Hidden category (Q5879327) template, or by directly including the __HIDDENCAT__ magic word.
  4. Add documentation to the template (e.g. by translating Template:Attached KML/doc, adjusting as necessary per any localisations made in the previous step) and to the module (please transfer/translate these instructions so that wikimedians who read your wiki but not the English Wikipedia can also set up the module and template on another wiki).

Tracking categories

The above documentation is transcluded from Module:Attached KML/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (create) pages.
Subpages of this module.

 -- Note: Originally written on English Wikipedia as [[w:en:Module:Attached_KML]]
 -- ##### Localisation (L10n) settings #####
 local L10n = {
	-- Template parameter names
	-- (replace values in quotes with local parameter names)
	para = {
		display = "display",
		from = "from",
		header = "header",
		title = "title",
		wikidata = "wikidata",
		demo = "demo",
	},
	-- Other configuration settings
	config = {
		-- controls the format used for inline display, can be set to "box" (default) or "line"
		-- "box" example: https://en.wikipedia.org/wiki/Template:Attached_KML
		-- "line" example: https://sv.wikipedia.org/wiki/Mall:KML
		inline_format = "box",
	},
	-- Other strings
	str = {
		inline = "inline", -- used with display parameter: (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline)
		title = "title", -- (as above)
		dsep = ",", -- separator between inline and title (comma in the example above)
		kml_prefix = "Template:Attached KML/", -- local KML files are stored as subpages of this location
		default_title = "Route map", -- default title for links at top of page, when title parameter not used in transclusion
		default_header = "", -- default header for links in inline box, when header parameter not used in transclusion
		kml_file = "KML file", -- text to display for link to raw KML file
		edit = "edit", -- text to display for link to edit KML file
		help = "help", -- text to display for help page link
		help_location	= "Help:Attached KML", -- page to link to for help page link
		err_prepend	= "Attached KML", -- text to prepend to the error messages, when shown at top of page (display=title)
		cat	= { -- tracking categories: full wikimarkup required, or set to the empty string ("") to not to track the condition
			wikidata_kml = "[[Category:Articles using KML from Wikidata]]", -- tracks mainspace articles using KML from Wikidata
			local_kml = "[[Category:Articles using KML not from Wikidata]]", -- tracks mainspace articles not using KML from Wikidata
			error_mqid = "[[Category:Attached KML errors|M]]", -- tracks malformed_qid error
			error_badqid = "[[Category:Attached KML errors|W]]", -- tracks bad_qid error
			error_noitem = "[[Category:Attached KML errors|N]]", -- tracks no_item error
			error_from = "[[Category:Attached KML errors|F]]", -- tracks bad_from error
			error_nokml = "[[Category:Attached KML errors|K]]", -- tracks no_kml error
		},
		line = { -- these strings are only needed if using 'inline_format = "line"' configuration
			start = "", -- wikitext to display at start of line, may include image markup, should start with a space
			separator = "", -- text to display between links to external mapping providers, should include spaces
		},
	}
 }

 L10n.str.err = { -- error messages
	malformed_qid	= "Error: malformed item id in <code><nowiki>|" .. L10n.para.wikidata .. "=</nowiki></code>",	-- item id doesn't match pattern (number with Q prefix)
	bad_qid		= "Error: item specified on Wikidata, or in <code><nowiki>|" .. L10n.para.wikidata .. "=</nowiki></code>, is not a KML file <small>(P31→Q26267864 not found)</small>",	-- item doesn't have a P31→Q26267864 statement
	no_item		= "Error: item specified in <code><nowiki>|" .. L10n.para.wikidata .. "=</nowiki></code> not found on Wikidata",	-- item not found on wikidata
	bad_from	= "Error: KML file not found, check <code><nowiki>|" .. L10n.para.from .. "=</nowiki></code>",	-- KML specified by from parameter doesn't exist
	no_kml		= "Error: KML file not found",	-- no KML file found
 }

 -- Masks for external mapping providers, in the form:
 -- externalLinkMasks[index-number] = { short = "short-label", long = "long-label", link = "url" }'
 -- The short label is used for the title links; the long label is used for the inline links
 -- Links in the output will be ordered by index-number
 -- Instead of kml file's raw url or encoded raw url, use __KML_URL__ or __KML_URL_E__
 local externalLinks = {}
 --externalLinks[1] = { 
 --	short = "Bing",
 --	long = "Display on Bing Maps",
 --	link = "http://www.bing.com/maps/?mapurl=__KML_URL__"
 --}

 -- #### End of L10n settings ####

 -- Table of available wikis, in the order that they are to be searched for kml files
 -- (once a kml file is found, further sites are not checked)
 local sites = {
	{
		mw.ustring.match( mw.site.server, "%w+" ) .. mw.ustring.gsub( mw.ustring.lower(mw.site.siteName), "[mp]edia", ""), 
		mw.ustring.sub(mw.site.server, 3),
		""
	}, -- local wiki (listed first so local files can override files on other wikis)
	{ "commonswiki", "commons.wikimedia.org", "c:" }, -- Commons would be a logical central repository for KML files (but has no files as of August 2016)
	{ "enwiki", "en.wikipedia.org", "w:en:" }, -- largest source of KML files (as of August 2016)
	{ "bnwiki", "bn.wikipedia.org", "w:bn:" }, -- other sites with a KML template, listed in alphabetical order
	{ "cswiki", "cs.wikipedia.org", "w:cs:" },
	{ "fawiki", "fa.wikipedia.org", "w:fa:" },
	{ "frwiki", "fr.wikipedia.org", "w:fr:" },
	{ "jawiki", "ja.wikipedia.org", "w:ja:" },
	{ "mlwiki", "ml.wikipedia.org", "w:ml:" },
	{ "svwiki", "sv.wikipedia.org", "w:sv:" },
	{ "zhwiki", "zh.wikipedia.org", "w:zh:" },
 }

 local p = {}

 local function setCleanArgs(argsTable)
	local cleanArgs = {}
	for key, val in pairs(argsTable) do
		if type(val) == 'string' then
			val = val:match('^%s*(.-)%s*$')
			if val ~= '' then
				cleanArgs[key] = val
			end
		else
			cleanArgs[key] = val
		end
	end
	return cleanArgs
 end

 local function safeReplace(string, pattern, replacement)
	-- avoids "Lua error: invalid capture index" that occurs with string.gsub when the replacement contains one or more literal % character
	local nonpattern_parts = mw.text.split( string, pattern )
	return table.concat(nonpattern_parts, replacement)
 end

 local function makeTitleWikitext(titletext, err)
	if err and L10n.str.err_prepend then
		err = mw.ustring.gsub( err, ">", ">" .. L10n.str.err_prepend .. " ", 1 )
	end

	local titleLinks = {}
	for i, v in ipairs( externalLinks ) do
		titleLinks[i] = mw.ustring.format( "[%s %s]", v.link , v.short)
	end
	return mw.getCurrentFrame():extensionTag{
				name = 'indicator',
				args = { name = 'attached-kml' },
				content = mw.ustring.format(
					"<span id=\"coordinates\">\'\'\'%s\'\'\': %s</span>",
					titletext,
					err or table.concat(titleLinks, " / ")
				)
			}
 end

 local function makeInlineWikitext(headertext, url, err)
	local inlineLinks = {}
	for i, v in ipairs( externalLinks ) do
		inlineLinks[i] = mw.ustring.format("[%s %s]", v.link , v.long)
	end
	local editUrl = mw.ustring.gsub( url, "action=raw", "action=edit" )
	local wiki_link_class
	if mw.ustring.find( editUrl, mw.site.server, 1, true ) then
		wiki_link_class = "plainlinks"
	else
		wiki_link_class = ""
	end

	if L10n.config.inline_format == "line" then
		return mw.ustring.format(
			"<li>%s%s%s (<span class=\"%s\">[%s %s] <span style=\"font-size:85%%;\">([%s %s] • [[%s|%s]])</span></span>)</li>",
			headertext, L10n.str.line.start,
			err or table.concat(inlineLinks, L10n.str.line.separator),
			wiki_link_class, url, L10n.str.kml_file, editUrl, L10n.str.edit,
			L10n.str.help_location, L10n.str.help
		)
	end
	
	local text = mw.ustring.format(
		'%s<span class="%s">\'\'\'[%s %s]\'\'\' ([%s %s] • [[%s|%s]])</span>',
		headertext, wiki_link_class, url, L10n.str.kml_file, editUrl,
		L10n.str.edit, L10n.str.help_location, L10n.str.help
	)
	
	if err or #inlineLinks > 0 then
		text = mw.ustring.format(
			"%s<ul><li>%s</li></ul>",
			text,
			err or table.concat(inlineLinks, "</li><li>")
		)
	end
	
	return require('Module:Side box')._main({
		class = 'attached-kml',
		text = text
	})
 end

 local function makeKmldataDiv(link, s_index)
	return mw.ustring.format(
		'<div class="kmldata" data-server="%s" title="%s">[[%s%s]][[Category:Pages using gadget WikiMiniAtlas]]</div>',
		sites[s_index][2], link, sites[s_index][3], link
	)
 end

 local function makeError(msg, cat)
	return mw.ustring.format(
		'<strong class="attached-kml-error">%s</strong>%s',
		msg,
		mw.title.getCurrentTitle():inNamespaces(0, 118) and cat or ''
	)
 end

 local function getUrlFromQid( kml_qid )
	local pcall_result, kml_entity = pcall(mw.wikibase.getEntity, kml_qid)
	if not pcall_result then return nil, nil, nil, makeError(L10n.str.err.no_item, L10n.str.cat.error_noitem) end -- Error if entity doesn't exist

	local p31_claim = kml_entity:getBestStatements("P31") -- P31 is property "instance of"
	local has_good_p31
	for k, v in pairs( p31_claim ) do
		if (p31_claim[k] and p31_claim[k].mainsnak.snaktype == "value" and
			p31_claim[k].mainsnak.datavalue.type == "wikibase-entityid" and
			p31_claim[k].mainsnak.datavalue.value["numeric-id"] == 26267864) then
			has_good_p31 = true
		end
	end
	if not (has_good_p31) then -- Error if item isn't a kml file
		return nil, nil, nil, makeError(L10n.str.err.bad_qid, L10n.str.cat.error_badqid)
	end 

	local kml_sitelink
	local kml_siteindex
	local kml_url
	for i, v in ipairs( sites ) do
		kml_sitelink = kml_entity:getSitelink( v[1] )
		if kml_sitelink then
			kml_url = "https://" .. v[2] .. "/w/index.php?title=" .. mw.uri.encode( kml_sitelink, "WIKI" ) .. "&action=raw"
			kml_siteindex = i
		end
		if kml_url then break end
	end
	return kml_url or nil, kml_sitelink or nil, kml_siteindex or nil, nil
 end

 -- Attempts to get url from linked wikidata items, will return nil if it can't
 local function getUrlFromWikidata()
	local entity = mw.wikibase.getEntityObject()
	if not entity then return nil end			

	local kml_claim = entity:getBestStatements("P3096")	-- P3096 is property "KML file"
	
	if kml_claim then
		-- get the QID of the first value of the property
		if (kml_claim[1] and kml_claim[1].mainsnak.snaktype == "value" and kml_claim[1].mainsnak.datavalue.type == "wikibase-entityid") then
			local kml_qid = "Q" .. kml_claim[1].mainsnak.datavalue.value["numeric-id"]
			return getUrlFromQid( kml_qid )
		else
			return nil	-- TODO: error message
		end
	else
		return nil	-- TODO: error message
	end
 end

 function p.main(frame)
	local parent = frame.getParent(frame)
	local Args = setCleanArgs(parent.args)

	local qid = Args[L10n.para.wikidata] or nil

	-- get KML file url
	local wikiUrl, wikiTitle, wikiLink, trackingWikitext, kmlError
	if not (Args[L10n.para.from]) then
		if not qid then
			wikiUrl, wikiLink, siteindex, kmlError = getUrlFromWikidata()
		elseif mw.ustring.find( qid, "^Q%d+" ) then
			wikiUrl, wikiLink, siteindex, kmlError = getUrlFromQid(qid)
		else
			kmlError = makeError(L10n.str.err.malformed_qid, L10n.str.cat.error_mqid)
		end
	end
	
	if not (wikiUrl) then
		-- FIXME? this smells bad. shouldn't need to make a new title of a to_string
		-- from the current title and then turn it into text form
		wikiLink = Args[L10n.para.from] or mw.title.new(tostring(mw.title.getCurrentTitle())).text
		wikiLink = L10n.str.kml_prefix .. wikiLink
		wikiTitle = mw.title.new( wikiLink )

		if not (wikiTitle.exists) and not (kmlError) then
			if Args[L10n.para.from] then
				kmlError = makeError(L10n.str.err.bad_from, L10n.str.cat.error_from)
			else
				kmlError = makeError(L10n.str.err.no_kml, L10n.str.cat.error_nokml)
			end
		end
		wikiUrl = wikiTitle:fullUrl("action=raw", "https")
		siteindex = 1
		trackingWikitext = mw.ustring.format(
			'<div title="KML & Wikidata" class="attached-kml-wikidata">KML is not from Wikidata</div>%s',
			mw.title.getCurrentTitle():inNamespace(0) and L10n.str.cat.local_kml or ''
		)
	else
		trackingWikitext = mw.ustring.format(
			'<div title="KML & Wikidata" class="attached-kml-wikidata">KML is from Wikidata</div>%s',
			mw.title.getCurrentTitle():inNamespace(0) and L10n.str.cat.wikidata_kml or ''
		)
	end
	
	wikiTitle = mw.title.new( wikiLink )
	if wikiTitle.exists then
		local transclusion = wikiTitle:getContent() -- hack to register the template as transcluded.
	end
		
	-- replace __KML_URL__ or __KML_URL_E__ with actual values
	local encodedWikiUrl = mw.uri.encode(wikiUrl, "PATH")
	for i, v in ipairs( externalLinks ) do
		local el1 = safeReplace( v.link, "__KML_URL__", wikiUrl )
		local el2 = safeReplace( el1, "__KML_URL_E__", encodedWikiUrl )
		externalLinks[i]["link"] = el2
	end

	-- suppress errors and categories if demo parameter is set
	if Args[L10n.para.demo] then
		kmlError = nil
		trackingWikitext = ""
	end

	local wikitext = ""
	if Args[L10n.para.display] then
		local display = mw.text.split(Args[L10n.para.display], '%s*' .. L10n.str.dsep .. '%s*')
		if display[1] == L10n.str.title or display[2] == L10n.str.title then
			wikitext = makeTitleWikitext(Args[L10n.para.title] or L10n.str.default_title, kmlError)
		end
		if display[1] == L10n.str.inline or display[2] == L10n.str.inline or (display[1] ~= L10n.str.title and display[2] ~= L10n.str.title) then
			local inlineWikitext = makeInlineWikitext(Args[L10n.para.header] or L10n.str.default_header, wikiUrl, kmlError)
			wikitext = wikitext .. inlineWikitext
		end
	else
		wikitext = makeInlineWikitext(Args[L10n.para.header] or L10n.str.default_header, wikiUrl, kmlError)
	end
	wikitext = wikitext .. makeKmldataDiv(wikiLink, siteindex) .. trackingWikitext

	return frame:extensionTag{
		name = 'templatestyles', args = { src = 'Module:Attached KML/styles.css' }
	} .. frame:preprocess( wikitext )

 end

 return p

AltStyle によって変換されたページ (->オリジナル) /