Module:Mapframe: Difference between revisions
Jump to navigation
Jump to search
>Evad37 (cleanup) |
>Evad37 (Tanslations and other localisation setting) |
||
Line 1: | Line 1: | ||
local | -- ##### Localisation (L10n) settings ##### | ||
display = | -- Replace values in quotes ("") with localised values | ||
text = | |||
local L10n = {} | |||
-- Template parameter names (unnumbered versions only) | |||
L10n.para = { | |||
display = "display", | |||
type = "type", | |||
id = "id", | |||
ids = "ids", | |||
from = "from", | |||
raw = "raw", | |||
title = "title", | |||
description = "description", | |||
strokeColor = "stroke-color", | |||
strokeColour = "stroke-colour", | |||
strokeWidth = "stroke-width", | |||
coord = "coord", | |||
marker = "marker", | |||
markerColor = "marker-color", | |||
markerColour = "marker-colour", | |||
text = "text", | |||
icon = "icon", | |||
zoom = "zoom", | |||
frame = "frame", | |||
plain = "plain", | |||
frameWidth = "frame-width", | |||
frameHeight = "frame-height", | |||
frameLat = "frame-lat", | |||
frameLatitude = "frame-latitude", | |||
frameLong = "frame-long", | |||
frameLongitude = "frame-longitude" | |||
} | |||
-- Names of other templates this module depends on | |||
L10n.template = { | |||
Coord = "Coord", | |||
WikidataCoord = "WikidataCoord" | |||
} | } | ||
-- Error messages | |||
L10n.error = { | |||
badDisplayPara = "Invalid display parameter" | |||
} | |||
-- Other strings | |||
L10n.str = { | |||
-- valid values for display parameter, e.g. (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline) | |||
inline = "inline", | |||
title = "title", | |||
dsep = ",", -- separator between inline and title (comma in the example above) | |||
-- valid values for type paramter | |||
line = "line", -- geoline feature (e.g. a road) | |||
shape = "shape", -- geoshape feature (e.g. a state or province) | |||
shapeInverse = "shape-inverse", -- geomask feature (the inverse of a geoshape) | |||
data = "data", -- geoJSON data page on Commons | |||
point = "point", -- single point feature (coordinates) | |||
-- valid values for icon, frame, and plain parameters | |||
affirmedWords = ' '..table.concat({ | |||
"add", | |||
"added", | |||
"affirm", | |||
"affirmed", | |||
"include", | |||
"included", | |||
"on", | |||
"true", | |||
"yes", | |||
"y" | |||
}, ' ')..' ', | |||
declinedWords = ' '..table.concat({ | |||
"decline", | |||
"declined", | |||
"exclude", | |||
"excluded", | |||
"false", | |||
"none", | |||
"not", | |||
"no", | |||
"n", | |||
"off", | |||
"omit", | |||
"omitted", | |||
"remove", | |||
"removed" | |||
}, ' ')..' ' | |||
} | |||
-- Default values for parameters | |||
L10n.defaults = { | |||
display = L10n.str.inline, | |||
text = "Map", | |||
frameWidth = "300", | |||
frameHeight = "200", | |||
marker = "marker", -- Do not translate. For valid alternate values, see https://www.mediawiki.org/wiki/Maps/Icons | |||
markerColor = "5E74F3", | |||
strokeColor = "#ff0000", | |||
strokeWidth = 6 | |||
} | |||
-- #### End of L10n settings #### | |||
function setCleanArgs(argsTable) | function setCleanArgs(argsTable) | ||
Line 23: | Line 121: | ||
function isAffirmed(val) | function isAffirmed(val) | ||
if not(val) then return false end | if not(val) then return false end | ||
return string.find(L10n.str.affirmedWords, ' '..val..' ', 1, true ) and true or false | |||
return string.find(affirmedWords, ' '..val..' ', 1, true ) and true or false | |||
end | end | ||
function isDeclined(val) | function isDeclined(val) | ||
if not(val) then return false end | if not(val) then return false end | ||
return string.find(L10n.str.declinedWords , ' '..val..' ', 1, true ) and true or false | |||
return string.find(declinedWords , ' '..val..' ', 1, true ) and true or false | |||
end | end | ||
function makeContent(args) | function makeContent(args) | ||
if args.raw then | if args[L10n.para.raw] then | ||
return args.raw | return args[L10n.para.raw] | ||
end | end | ||
local content = {}; | local content = {}; | ||
local contentIndex = ''; | local contentIndex = ''; | ||
while args[ | while args[L10n.para.type .. contentIndex] or args[L10n.para.from .. contentIndex] do | ||
local contentArgs = {} | local contentArgs = {} | ||
for k, v in pairs(args) do | for k, v in pairs(args) do | ||
Line 75: | Line 171: | ||
local coords | local coords | ||
local frame = mw.getCurrentFrame() | local frame = mw.getCurrentFrame() | ||
if args.coord then | if args[L10n.para.coord] then | ||
coords = frame:preprocess(args.coord) | coords = frame:preprocess(args[L10n.para.coord]) | ||
else | else | ||
coords = frame:preprocess('{{WikidataCoord|display=|'..(args.id or args.ids or mw.wikibase.getEntityIdForCurrentPage())..'}}') | coords = frame:preprocess('{{' .. L10n.template.WikidataCoord .. '|display=|' .. (args[L10n.para.id] or args[L10n.para.ids] or mw.wikibase.getEntityIdForCurrentPage()) .. '}}') | ||
end | end | ||
local lat, long = parseCoords(coords) | local lat, long = parseCoords(coords) | ||
Line 90: | Line 186: | ||
local data = {} | local data = {} | ||
if args.type == | if args[L10n.para.type] == L10n.str.point then | ||
data.type = "Feature" | data.type = "Feature" | ||
data.geometry = { | data.geometry = { | ||
Line 97: | Line 193: | ||
} | } | ||
data.properties = { | data.properties = { | ||
title = args.title or mw.getCurrentFrame():getParent():getTitle(), | title = args[L10n.para.title] or mw.getCurrentFrame():getParent():getTitle(), | ||
["marker-symbol"] = args.marker or | ["marker-symbol"] = args[L10n.para.marker] or L10n.defaults.marker, | ||
["marker-color"] = | ["marker-color"] = args[L10n.para.markerColor] or args[L10n.para.markerColour] or L10n.defaults.markerColor | ||
} | } | ||
else | else | ||
data.type = "ExternalData" | data.type = "ExternalData" | ||
if args.type == | if args[L10n.para.type] == L10n.str.data or args[L10n.para.from] then | ||
data.service = "page" | data.service = "page" | ||
elseif args.type == | elseif args[L10n.para.type] == L10n.str.line then | ||
data.service = "geoline" | data.service = "geoline" | ||
elseif args.type == | elseif args[L10n.para.type] == L10n.str.shape then | ||
data.service = "geoshape" | data.service = "geoshape" | ||
elseif | elseif argsargs[L10n.para.type] == L10n.str.shape-inverse then | ||
data.service = "geomask" | data.service = "geomask" | ||
end | end | ||
if args.id or args.ids or (not (args.from) and mw.wikibase.getEntityIdForCurrentPage()) then | if args[L10n.para.id] or args[L10n.para.ids] or (not (args[L10n.para.from]) and mw.wikibase.getEntityIdForCurrentPage()) then | ||
data.ids = args.id or args.ids or mw.wikibase.getEntityIdForCurrentPage() | data.ids = args[L10n.para.id] or args[L10n.para.ids] or mw.wikibase.getEntityIdForCurrentPage() | ||
else | else | ||
data.title = args.from | data.title = args[L10n.para.from] | ||
end | end | ||
data.properties = { | data.properties = { | ||
stroke = args[ | stroke = args[L10n.para.strokeColor] or args[L10n.para.strokeColour] or L10.defaults.strokeColor, | ||
["stroke-width"] = tonumber(args[ | ["stroke-width"] = tonumber(args[L10n.para.strokeWidth]) or L10n.defaults.strokeWidth | ||
} | } | ||
end | end | ||
data.properties.title = args.title or mw.getCurrentFrame():getParent():getTitle() | data.properties.title = args[L10n.para.title] or mw.getCurrentFrame():getParent():getTitle() | ||
if args.description then | if args[L10n.para.description] then | ||
data.properties.description = args.description | data.properties.description = args[L10n.para.description] | ||
end | end | ||
Line 136: | Line 232: | ||
function makeTagAttribs(args, isTitle) | function makeTagAttribs(args, isTitle) | ||
local attribs = {} | local attribs = {} | ||
if args.zoom then | if args[L10n.para.zoom] then | ||
attribs.zoom = args.zoom | attribs.zoom = args[L10n.para.zoom] | ||
end | end | ||
if isDeclined(args.icon) then | if isDeclined(args[L10n.para.icon]) then | ||
attribs.class = "no-icon" | attribs.class = "no-icon" | ||
end | end | ||
if args.type == | if args[L10n.para.type] == L10n.str.point then | ||
local lat, long = makeCoords(args, 'plainOutput') | local lat, long = makeCoords(args, 'plainOutput') | ||
attribs.latitude = tostring(lat) | attribs.latitude = tostring(lat) | ||
attribs.longitude = tostring(long) | attribs.longitude = tostring(long) | ||
end | end | ||
if isAffirmed(args.frame) and not(isTitle) then | if isAffirmed(args[L10n.para.frame]) and not(isTitle) then | ||
attribs.width = args[ | attribs.width = args[L10n.para.frameWidth] or L10n.defaults.frameWidth | ||
attribs.height = args[ | attribs.height = args[L10n.para.frameHeight] or L10n.defaults.frameHeight | ||
if args[ | if args[L10n.para.frameLat] or args[L10n.para.frameLatitude] then | ||
attribs.latitude = args[ | attribs.latitude = args[L10n.para.frameLat] or args[L10n.para.frameLatitude] | ||
end | end | ||
if args[ | if args[L10n.para.frameLong] or args[L10n.para.frameLongitude] then | ||
attribs.longitude = args[ | attribs.longitude = args[L10n.para.frameLong] or args[L10n.para.frameLongitude] | ||
end | end | ||
if isAffirmed(args.plain) then | if isAffirmed(args[L10n.para.plain]) then | ||
attribs.frameless = "1" | attribs.frameless = "1" | ||
else | else | ||
attribs.text = args.text or defaults.text | attribs.text = args[L10n.para.text] or L10n.defaults.text | ||
end | end | ||
else | else | ||
attribs.text = args.text or defaults.text | attribs.text = args[L10n.para.text] or L10n.defaults.text | ||
end | end | ||
return attribs | return attribs | ||
Line 178: | Line 274: | ||
function makeInlineOutput(args, tagContent) | function makeInlineOutput(args, tagContent) | ||
local tagName = 'maplink' | local tagName = 'maplink' | ||
if args.frame then | if args[L10n.para.frame] then | ||
tagName = 'mapframe' | tagName = 'mapframe' | ||
end | end | ||
Line 193: | Line 289: | ||
local tagContent = makeContent(args) | local tagContent = makeContent(args) | ||
local display = mw.text.split(args.display or defaults.display, '%s* | local display = mw.text.split(args[L10n.para.display] or L10n.defaults.display, '%s*' .. L10.str.dsep .. '%s*') | ||
local displayInTitle = display[1] == | local displayInTitle = display[1] == L10.str.title or display[2] == L10.str.title | ||
local displayInline = display[1] == | local displayInline = display[1] == L10.str.inline or display[2] == L10.str.inline | ||
local output | local output | ||
Line 205: | Line 301: | ||
output = makeInlineOutput(args, tagContent) | output = makeInlineOutput(args, tagContent) | ||
else | else | ||
error( | error(L10n.error.badDisplayPara) | ||
end | end | ||
Revision as of 01:07, 3 May 2018
Documentation for this module may be created at Module:Mapframe/doc
-- ##### Localisation (L10n) settings ##### -- Replace values in quotes ("") with localised values local L10n = {} -- Template parameter names (unnumbered versions only) L10n.para = { display = "display", type = "type", id = "id", ids = "ids", from = "from", raw = "raw", title = "title", description = "description", strokeColor = "stroke-color", strokeColour = "stroke-colour", strokeWidth = "stroke-width", coord = "coord", marker = "marker", markerColor = "marker-color", markerColour = "marker-colour", text = "text", icon = "icon", zoom = "zoom", frame = "frame", plain = "plain", frameWidth = "frame-width", frameHeight = "frame-height", frameLat = "frame-lat", frameLatitude = "frame-latitude", frameLong = "frame-long", frameLongitude = "frame-longitude" } -- Names of other templates this module depends on L10n.template = { Coord = "Coord", WikidataCoord = "WikidataCoord" } -- Error messages L10n.error = { badDisplayPara = "Invalid display parameter" } -- Other strings L10n.str = { -- valid values for display parameter, e.g. (|display=inline) or (|display=title) or (|display=inline,title) or (|display=title,inline) inline = "inline", title = "title", dsep = ",", -- separator between inline and title (comma in the example above) -- valid values for type paramter line = "line", -- geoline feature (e.g. a road) shape = "shape", -- geoshape feature (e.g. a state or province) shapeInverse = "shape-inverse", -- geomask feature (the inverse of a geoshape) data = "data", -- geoJSON data page on Commons point = "point", -- single point feature (coordinates) -- valid values for icon, frame, and plain parameters affirmedWords = ' '..table.concat({ "add", "added", "affirm", "affirmed", "include", "included", "on", "true", "yes", "y" }, ' ')..' ', declinedWords = ' '..table.concat({ "decline", "declined", "exclude", "excluded", "false", "none", "not", "no", "n", "off", "omit", "omitted", "remove", "removed" }, ' ')..' ' } -- Default values for parameters L10n.defaults = { display = L10n.str.inline, text = "Map", frameWidth = "300", frameHeight = "200", marker = "marker", -- Do not translate. For valid alternate values, see https://www.mediawiki.org/wiki/Maps/Icons markerColor = "5E74F3", strokeColor = "#ff0000", strokeWidth = 6 } -- #### End of L10n settings #### 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 function isAffirmed(val) if not(val) then return false end return string.find(L10n.str.affirmedWords, ' '..val..' ', 1, true ) and true or false end function isDeclined(val) if not(val) then return false end return string.find(L10n.str.declinedWords , ' '..val..' ', 1, true ) and true or false end function makeContent(args) if args[L10n.para.raw] then return args[L10n.para.raw] end local content = {}; local contentIndex = ''; while args[L10n.para.type .. contentIndex] or args[L10n.para.from .. contentIndex] do local contentArgs = {} for k, v in pairs(args) do if string.match(k, '.*'..contentIndex) then contentArgs[string.gsub(k, contentIndex, '')] = v end end if contentIndex == '' then contentIndex = 1 end content[contentIndex] = makeContentJson(contentArgs) contentIndex = contentIndex + 1 end --Single item, no array needed if #content==1 then return content[1] end --Multiple items get placed in a FeatureCollection local contentArray = '[\n' .. table.concat( content, ',\n') .. '\n]' return contentArray end function parseCoords(coords) local parts = mw.text.split((mw.ustring.match(coords,'[%.%d]+°[NS] [%.%d]+°[EW]') or ''), ' ') latParts = mw.text.split(parts[1], '°') longParts = mw.text.split(parts[2], '°') if latParts[2] == 'S' then latParts[1] = '-'..latParts[1] end if longParts[2] == 'W' then longParts[1] = '-'..longParts[1] end return tonumber(latParts[1]), tonumber(longParts[1]) end function makeCoords(args, plainOutput) local coords local frame = mw.getCurrentFrame() if args[L10n.para.coord] then coords = frame:preprocess(args[L10n.para.coord]) else coords = frame:preprocess('{{' .. L10n.template.WikidataCoord .. '|display=|' .. (args[L10n.para.id] or args[L10n.para.ids] or mw.wikibase.getEntityIdForCurrentPage()) .. '}}') end local lat, long = parseCoords(coords) if plainOutput then return lat, long end return {[0] = long, [1] = lat} end function makeContentJson(args) local data = {} if args[L10n.para.type] == L10n.str.point then data.type = "Feature" data.geometry = { type = "Point", coordinates = makeCoords(args) } data.properties = { title = args[L10n.para.title] or mw.getCurrentFrame():getParent():getTitle(), ["marker-symbol"] = args[L10n.para.marker] or L10n.defaults.marker, ["marker-color"] = args[L10n.para.markerColor] or args[L10n.para.markerColour] or L10n.defaults.markerColor } else data.type = "ExternalData" if args[L10n.para.type] == L10n.str.data or args[L10n.para.from] then data.service = "page" elseif args[L10n.para.type] == L10n.str.line then data.service = "geoline" elseif args[L10n.para.type] == L10n.str.shape then data.service = "geoshape" elseif argsargs[L10n.para.type] == L10n.str.shape-inverse then data.service = "geomask" end if args[L10n.para.id] or args[L10n.para.ids] or (not (args[L10n.para.from]) and mw.wikibase.getEntityIdForCurrentPage()) then data.ids = args[L10n.para.id] or args[L10n.para.ids] or mw.wikibase.getEntityIdForCurrentPage() else data.title = args[L10n.para.from] end data.properties = { stroke = args[L10n.para.strokeColor] or args[L10n.para.strokeColour] or L10.defaults.strokeColor, ["stroke-width"] = tonumber(args[L10n.para.strokeWidth]) or L10n.defaults.strokeWidth } end data.properties.title = args[L10n.para.title] or mw.getCurrentFrame():getParent():getTitle() if args[L10n.para.description] then data.properties.description = args[L10n.para.description] end return mw.text.jsonEncode(data) end function makeTagAttribs(args, isTitle) local attribs = {} if args[L10n.para.zoom] then attribs.zoom = args[L10n.para.zoom] end if isDeclined(args[L10n.para.icon]) then attribs.class = "no-icon" end if args[L10n.para.type] == L10n.str.point then local lat, long = makeCoords(args, 'plainOutput') attribs.latitude = tostring(lat) attribs.longitude = tostring(long) end if isAffirmed(args[L10n.para.frame]) and not(isTitle) then attribs.width = args[L10n.para.frameWidth] or L10n.defaults.frameWidth attribs.height = args[L10n.para.frameHeight] or L10n.defaults.frameHeight if args[L10n.para.frameLat] or args[L10n.para.frameLatitude] then attribs.latitude = args[L10n.para.frameLat] or args[L10n.para.frameLatitude] end if args[L10n.para.frameLong] or args[L10n.para.frameLongitude] then attribs.longitude = args[L10n.para.frameLong] or args[L10n.para.frameLongitude] end if isAffirmed(args[L10n.para.plain]) then attribs.frameless = "1" else attribs.text = args[L10n.para.text] or L10n.defaults.text end else attribs.text = args[L10n.para.text] or L10n.defaults.text end return attribs end function makeTitleOutput(args, tagContent) local titleTag = mw.text.tag('maplink', makeTagAttribs(args, true), tagContent) local spanAttribs = { style = "font-size: small;", id = "coordinates" } return mw.text.tag('span', spanAttribs, titleTag) end function makeInlineOutput(args, tagContent) local tagName = 'maplink' if args[L10n.para.frame] then tagName = 'mapframe' end return mw.text.tag(tagName, makeTagAttribs(args), tagContent) end local p = {} function p.main(frame) local parent = frame.getParent(frame) local args = setCleanArgs(parent.args) local tagContent = makeContent(args) local display = mw.text.split(args[L10n.para.display] or L10n.defaults.display, '%s*' .. L10.str.dsep .. '%s*') local displayInTitle = display[1] == L10.str.title or display[2] == L10.str.title local displayInline = display[1] == L10.str.inline or display[2] == L10.str.inline local output if displayInTitle and displayInline then output = makeTitleOutput(args, tagContent) .. makeInlineOutput(args, tagContent) elseif displayInTitle then output = makeTitleOutput(args, tagContent) elseif displayInline then output = makeInlineOutput(args, tagContent) else error(L10n.error.badDisplayPara) end return frame:preprocess(output) end return p