This is the module sandbox page for Module:Module sandbox (diff). |
Welcome to Module:Module sandbox/sandbox, a Wikipedia module sandbox. This page is itself a module, and it allows you to carry out experiments related to module editing. If you wish to experiment with article editing, use the Wikipedia Sandbox or your own user sandbox.
To edit, click the edit tab above, make your changes and click the Publish changes button when finished. Please do not place malicious Lua code here, or copyrighted, offensive, illegal or libelous content in the sandboxes. For assistance with Lua coding, try the technical forum at the Village Pump. There are also several template sandboxes you can use to carry out experiments:
You can also conduct tests using the Wikipedia Sandbox. For instance, to invoke this module there, edit it so that it includes: {{#invoke:Module sandbox}} |
More info
Sandbox games |
Usage
edit{{#invoke:Module sandbox|function_name}}
-- 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, q = {}, {}
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]]</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
local Args = setCleanArgs(frame.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
function q.main(frame)
local entity = mw.wikibase.getEntity(frame.args.Q)
local entity = mw.wikibase.getEntity()
local kml = entity:getBestStatements("P3096")
if entity==nil then
return frame:preprocess("Hello".."Bye")
else
return frame:preprocess("Hello"..tostring(kml[1]).."Bye")
end
end
return q