Module:Infobox mapframe: Difference between revisions
Appearance
Detect if the default value of "{{{coordinates}}}" is being passed by {{Parameter names example}} and automatically turn off |
No edit summary |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
local yesno = require('Module:Yesno') | local yesno = require('Module:Yesno') | ||
local infoboxImage = require('Module:InfoboxImage').InfoboxImage | local infoboxImage = require('Module:InfoboxImage').InfoboxImage | ||
-- Wikibase safety layer | |||
local wikibase = mw.wikibase | |||
local function hasWikibase() | |||
return wikibase ~= nil | |||
end | |||
-- Defaults | -- Defaults | ||
| Line 8: | Line 14: | ||
local DEFAULT_FRAME_HEIGHT = "200" | local DEFAULT_FRAME_HEIGHT = "200" | ||
local DEFAULT_ZOOM = 10 | local DEFAULT_ZOOM = 10 | ||
local util = {} | |||
function util.noop() | |||
return "" | |||
end | |||
function util.trimArgs(argsTable) | |||
function trimArgs(argsTable) | |||
local cleanArgs = {} | local cleanArgs = {} | ||
for key, val in pairs(argsTable) do | for key, val in pairs(argsTable) do | ||
if type(val) == 'string' then | if type(val) == 'string' then | ||
val = val:match('^%s*(.-)%s*$') | val = val:match('^%s*(.-)%s*$') | ||
if val ~= '' then | if val ~= '' then cleanArgs[key] = val end | ||
else | else | ||
cleanArgs[key] = val | cleanArgs[key] = val | ||
| Line 37: | Line 34: | ||
end | end | ||
function getBestStatement(item_id, property_id) | -- SAFE Wikidata access | ||
if not(item_id | function util.getBestStatement(item_id, property_id) | ||
if not hasWikibase() then return false end | |||
if not item_id then return false end | |||
local statements = | if not wikibase.isValidEntityId(item_id) then return false end | ||
if not statements or #statements == 0 then | if not wikibase.entityExists(item_id) then return false end | ||
local statements = wikibase.getBestStatements(item_id, property_id) | |||
if not statements or #statements == 0 then return false end | |||
end | |||
local snak = statements[1].mainsnak | |||
return | if snak and snak.snaktype == 'novalue' then return false end | ||
end | |||
return statements[1] | |||
return | |||
end | end | ||
function | function util.getStatementValue(statement) | ||
return statement and statement.mainsnak | |||
return | and statement.mainsnak.datavalue | ||
and statement.mainsnak.datavalue.value | |||
end | end | ||
function | function util.relatedEntity(item_id, property_id) | ||
local val = util.getStatementValue(util.getBestStatement(item_id, property_id)) | |||
return val and val.id or nil | |||
end | end | ||
function util.shouldAutoRun(frame) | |||
local pargs = frame:getParent().args | |||
function shouldAutoRun(frame) | local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or "")) | ||
local onByDefault = (explicitlyOn == nil) and yesno(frame.args.onByDefault or "", false) | |||
local pargs = frame | |||
local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or "")) | |||
local onByDefault = (explicitlyOn == nil) and yesno | |||
return explicitlyOn or onByDefault | return explicitlyOn or onByDefault | ||
end | end | ||
function argsFromAuto(frame) | function util.argsFromAuto(frame) | ||
local args = getArgs(frame, { parentFirst = true }) | |||
local fixed = {} | |||
local args = getArgs(frame, {parentFirst = true}) | for k, v in pairs(args) do | ||
local name = k:match("^mapframe%-(.+)$") | |||
if name then | |||
local | fixed[name] = v | ||
for | elseif (k == "coord" or k == "coordinates") and not fixed.coord then | ||
local | fixed.coord = v | ||
if | elseif (k == "id" or k == "qid") and not fixed.id then | ||
fixed.id = v | |||
elseif | |||
end | end | ||
end | end | ||
return | return fixed | ||
end | |||
-- Caption | |||
local function getLabel(id) | |||
return hasWikibase() and id and wikibase.getLabel(id) | |||
end | end | ||
local p = {} | local p = {} | ||
p. | p._caption = function(args) | ||
if args.caption then return args.caption end | |||
local label = getLabel(args.id) | |||
if args.caption then | return label and ("Location of " .. label) or "" | ||
local | |||
end | end | ||
function | p._main = function(config) | ||
config = util.trimArgs(config) | |||
local args = {} | |||
args.frame = "yes" | |||
args.plain = "yes" | |||
args["frame-width"] = config.width or DEFAULT_FRAME_WIDTH | |||
args["frame-height"] = config.height or DEFAULT_FRAME_HEIGHT | |||
local coord = config.coord or config.coordinates | |||
local | local id = config.id or (hasWikibase() and wikibase.getEntityIdForCurrentPage()) | ||
local | |||
if not coord and not id then | |||
return false, "" | |||
if not | |||
return | |||
end | end | ||
args.zoom = config.zoom or DEFAULT_ZOOM | |||
-- ( | |||
-- Point marker only (safe fallback) | |||
if coord then | |||
args.type = "point" | |||
args.coord = coord | |||
end | end | ||
local map = mf._main(args) | |||
return true, map | |||
end | |||
p.autoWithCaption = function(frame) | |||
if not util.shouldAutoRun(frame) then return "" end | |||
args | local args = util.argsFromAuto(frame) | ||
local ok, map = p._main(args) | |||
if not ok then return map end | |||
map = frame:preprocess(map) | |||
local caption = p._caption(args) | |||
local html = mw.html.create() | |||
local | html:wikitext(map) | ||
html:tag("div") | |||
:addClass("infobox-caption") | |||
:wikitext(caption) | |||
return tostring(html) | |||
end | end | ||
return p | return p | ||
Latest revision as of 18:55, 9 May 2026
Documentation for this module may be created at Module:Infobox mapframe/doc
local mf = require('Module:Mapframe')
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local infoboxImage = require('Module:InfoboxImage').InfoboxImage
-- Wikibase safety layer
local wikibase = mw.wikibase
local function hasWikibase()
return wikibase ~= nil
end
-- Defaults
local DEFAULT_FRAME_WIDTH = "270"
local DEFAULT_FRAME_HEIGHT = "200"
local DEFAULT_ZOOM = 10
local util = {}
function util.noop()
return ""
end
function util.trimArgs(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
-- SAFE Wikidata access
function util.getBestStatement(item_id, property_id)
if not hasWikibase() then return false end
if not item_id then return false end
if not wikibase.isValidEntityId(item_id) then return false end
if not wikibase.entityExists(item_id) then return false end
local statements = wikibase.getBestStatements(item_id, property_id)
if not statements or #statements == 0 then return false end
local snak = statements[1].mainsnak
if snak and snak.snaktype == 'novalue' then return false end
return statements[1]
end
function util.getStatementValue(statement)
return statement and statement.mainsnak
and statement.mainsnak.datavalue
and statement.mainsnak.datavalue.value
end
function util.relatedEntity(item_id, property_id)
local val = util.getStatementValue(util.getBestStatement(item_id, property_id))
return val and val.id or nil
end
function util.shouldAutoRun(frame)
local pargs = frame:getParent().args
local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or ""))
local onByDefault = (explicitlyOn == nil) and yesno(frame.args.onByDefault or "", false)
return explicitlyOn or onByDefault
end
function util.argsFromAuto(frame)
local args = getArgs(frame, { parentFirst = true })
local fixed = {}
for k, v in pairs(args) do
local name = k:match("^mapframe%-(.+)$")
if name then
fixed[name] = v
elseif (k == "coord" or k == "coordinates") and not fixed.coord then
fixed.coord = v
elseif (k == "id" or k == "qid") and not fixed.id then
fixed.id = v
end
end
return fixed
end
-- Caption
local function getLabel(id)
return hasWikibase() and id and wikibase.getLabel(id)
end
local p = {}
p._caption = function(args)
if args.caption then return args.caption end
local label = getLabel(args.id)
return label and ("Location of " .. label) or ""
end
p._main = function(config)
config = util.trimArgs(config)
local args = {}
args.frame = "yes"
args.plain = "yes"
args["frame-width"] = config.width or DEFAULT_FRAME_WIDTH
args["frame-height"] = config.height or DEFAULT_FRAME_HEIGHT
local coord = config.coord or config.coordinates
local id = config.id or (hasWikibase() and wikibase.getEntityIdForCurrentPage())
if not coord and not id then
return false, ""
end
args.zoom = config.zoom or DEFAULT_ZOOM
-- Point marker only (safe fallback)
if coord then
args.type = "point"
args.coord = coord
end
local map = mf._main(args)
return true, map
end
p.autoWithCaption = function(frame)
if not util.shouldAutoRun(frame) then return "" end
local args = util.argsFromAuto(frame)
local ok, map = p._main(args)
if not ok then return map end
map = frame:preprocess(map)
local caption = p._caption(args)
local html = mw.html.create()
html:wikitext(map)
html:tag("div")
:addClass("infobox-caption")
:wikitext(caption)
return tostring(html)
end
return p