Module:Coordinates
This template is used on a very large number of pages. To avoid large-scale disruption and unnecessary server load, any changes should first be tested in this template's /sandbox or /testcases subpage, or in your own user space. The tested changes can then be added in one single edit to this template. Please consider discussing any changes on the talk page before implementing them. |
Careful, this function is live, and called by {{Location}} template. The documentation might not be complete
This module provides most of the logic behind {{location}} and related geolocation templates. It provides several methods visible to the templates:
- {{#Invoke:Coordinates | parseAttribute| attribute string | attribute name }} : parse {{location}} attribute parameter attribute string and return value of the attribute name parameter
- {{#Invoke:Coordinates | getHeader| attribute string }} : parse {{location}} attribute parameter attribute string and return the numeric value of the header attribute.
- {{#Invoke:Coordinates | GeoHack_link| lat=... | lon=... |lang=xx | site=... | globe=... }}: creates link to GeoHack tool and display location coordinates. The URLs are based on website and latitude/longitude coordinates. Language is used so it can be passes to the website. Globe parameter is used to allow specifying coordinates on planets other than earth.
- {{#Invoke:Coordinates | lat_lon| lat=... | lon=... |lang=xx }}: create coordinate location string based on decimal degrees latitude and longitude number. Language is used to localize the presentation of the numbers.
- {{#Invoke:Coordinates | deg2dms| degrees|lang=xx }}: create dms (degree/minute/second) string based on decimal degrees number. Language is used to localize the presentation of the numbers.
- {{#Invoke:Coordinates | externalLink| site=... | globe=... | lat=... | lon=... |lang=xx }}: create URLs for different sites which are used by coordinate location templates. The URLs are based on website and latitude/longitude coordinates. Language is used so it can be passes to the website. Globe parameter is used to allow specifying coordinates on planets other than earth.
Examples
Functions:
- deg2dms(degree, degree_precision, language)
- {{#invoke:Coordinates| deg2dms | 12.3456789}} will display "12° 20′ 44,44″"
- {{#invoke:Coordinates| deg2dms | 12.3456789 |1}} will display "12°"
- {{#invoke:Coordinates| deg2dms | 12.3456789 |1e-1}} will display "12° 21′"
- {{#invoke:Coordinates| deg2dms | 12.3456789 |1e-3}} will display "12° 20′ 44″"
- {{#invoke:Coordinates| deg2dms | 12.3456789 |1e-4}} will display "12° 20′ 44,4″"
- {{#invoke:Coordinates| deg2dms | 12.3456789 |1e-5}} will display "12° 20′ 44,44″"
- lat_lon
- {{#invoke:Coordinates| lat_lon | lat=51.48 | lon=0}} will display "51° 28′ 48″ N, 0° 00′ 00″ E"
- GeoHack_link
- {{#invoke:Coordinates| GeoHack_link | lat=51.48123 | lon=0}} will display
- {{#invoke:Coordinates| GeoHack_link | lat=51.48123 | lon=0 | lang=en }} will display
- {{#invoke:Coordinates| GeoHack_link | lat=51.48123 | lon=0 | lang=ru }} will display
- {{#invoke:Coordinates| GeoHack_link | lat= | lon=0 | lang=ru }} (with missing latitude value) will display "latitude, longitude"
- externalLinksSection
- {{#invoke:Coordinates| externalLinksSection | globe = Earth| lat=51.48 | lon=0 | lang=en | namespace=File}} displays "OpenStreetMap - Google Earth"
- {{#invoke:Coordinates| externalLinksSection | globe = Earth| lat=51.48 | lon=0 | lang=en | namespace=Category}} displays "OpenStreetMap - Google Earth - Proximityrama"
- {{#invoke:Coordinates| externalLinksSection | globe = Earth| lat=51.48 | lon=0 | lang=ru | namespace=Category}} displays "OpenStreetMap - Google Планете Земля - Proximityrama"
- {{#invoke:Coordinates| externalLinksSection | globe = Mars| lat=51.48 | lon=0 | lang=en | namespace=File}} displays "Google Maps"
- {{#invoke:Coordinates| externalLinksSection | globe = Moon| lat=51.48 | lon=0 | lang=en | namespace=File}} displays "Google Maps"
- LocationTemplateCore
- {{#invoke:Coordinates| LocationTemplateCore | globe = Earth| lat=51.48 | lon=0 | lang=en | namespace=File| attributes=elevation:10_heading:W | mode=camera | bare = 1| secondary=1}} displays "
"View this and other nearby images on: OpenStreetMap - Google Earth - {{#invoke:Coordinates| LocationTemplateCore | globe = Earth| lat=51.48 | lon=0 | lang=en | namespace=File| attributes=elevation:10_heading:W | mode=camera | bare = 0| secondary=1}} displays "
"Camera location View this and other nearby images on: OpenStreetMap - Google Earth
- {{#invoke:Coordinates| LocationTemplateCore | globe = Earth| lat=51.48 | lon=0 | lang=en | namespace=File| attributes=elevation:10_heading:W | mode=camera | bare = 1| secondary=1}} displays "
See testcases to see more examples.
Dependencies
Relies on Module:I18n/coordinates for all of the internationalization translations.
--[[ This module is intended to provide functionality of {{location}} and related templates. Please do not modify this code without applying the changes first at Module:Coordinates/sandbox and testing at Module:Coordinates/sandbox/testcases and Module talk:Coordinates/sandbox/testcases. Authors and maintainers: * User:Jarekt * User:Ebraminio Functions: *function coordinates.LocationTemplateCore(frame) **function coordinates.GeoHack_link(frame) ***function coordinates.lat_lon(frame) ****function coordinates._deg2dms(deg,lang) ***function coordinates.externalLink(frame) ****function coordinates._externalLink(site, globe, latStr, lonStr, lang, attributes) **function coordinates._getHeading(attributes) **function coordinates.externalLinksSection(frame) ***function coordinates._externalLink(site, globe, latStr, lonStr, lang, attributes) *function coordinates.getHeading(frame) *function coordinates.deg2dms(frame) ]] coordinates = {}; -- ======================================= -- === Dependencies ====================== -- ======================================= local i18n = require('Module:I18n/coordinates') -- get localized translations of site names local Fallback = require('Module:Fallback') -- get fallback functions local yesno = require('Module:Yesno') -- ======================================= -- === Hardwired parameters ============== -- ======================================= -- Angles associated with each abriviation of compass point names. See [[:en:Points of the compass]] local compass_points = { N = 0, NBE = 11.25, NNE = 22.5, NEBN = 33.75, NE = 45, NEBE = 56.25, ENE = 67.5, EBN = 78.75, E = 90, EBS = 101.25, ESE = 112.5, SEBE = 123.75, SE = 135, SEBS = 146.25, SSE = 157.5, SBE = 168.75, S = 180, SBW = 191.25, SSW = 202.5, SWBS = 213.75, SW = 225, SWBW = 236.25, WSW = 247.5, WBS = 258.75, W = 270, WBN = 281.25, WNW = 292.5, NWBW = 303.75, NW = 315, NWBN = 326.25, NNW = 337.5, NBW = 348.75, } -- URL definitions for different sites. Strings: $lat, $lon, $lang, $attr, $page will be -- replaced with latitude, longitude, language code, GeoHack attribution parameters and full-page-name strings. local SiteURL = { GeoHack = '//tools.wmflabs.org/geohack/geohack.php?pagename=$page¶ms=$lat_N_$lon_E_$attr&language=$lang', GoogleEarth = '{{fullurl:toollabs:geocommons/earth.kml|latdegdec=$lat&londegdec=$lon&scale=10000&commons=1}}', Proximityrama = '{{fullurl:toollabs:geocommons/proximityrama|latlon=$lat,$lon}}', OpenStreetMap = '{{fullurl:toollabs:wiwosm/osm-on-ol/commons-on-osm.php|zoom=16&lat=$lat&lon=$lon}}', GoogleMaps = { Mars = '//www.google.com/mars/#lat=$lat&lon=$lon&zoom=8', Moon = '//www.google.com/moon/#lat=$lat&lon=$lon&zoom=8', Earth = 'https://maps.google.com/maps?ll=$lat,$lon&spn=0.01,0.01&t=k&q=http://tools.wmflabs.org/geocommons/web.kml&hl=$lang' } } -- Categories local CoorCat = { File = '[[Category:Media with locations]]', Gallery = '[[Category:Galleries with coordinates]]', Category = '[[Category:Categories with coordinates]]', globe = '[[Category:Media with %s locations]]', default = '[[Category:Media with default locations]]', attribute = '[[Category:Media with erroneous geoloaction attributes]]', erroneous = '[[Category:Media with erroneous locations]]<span style="color:red;font-weight:bold">Error: Invalid parameters!</span>\n' } local NoLatLonString = 'latitude, longitude' -- ======================================= -- === Functions ========================= -- ======================================= -- parse attribute variable returning desired field function coordinates.parseAttribute(frame) return string.match(mw.text.decode(frame.args[1]), mw.text.decode(frame.args[2]) .. ':' .. '([^_]*)') or '' end --[[============================================================================ Parse attribute variable returning heading field. If heading is a string than try to convert it to an angle ==============================================================================]] function coordinates.getHeading(frame) local attributes if frame.args[1] then attributes = frame.args[1] elseif frame.args.attributes then attributes = frame.args.attributes else return '' end local hNum = coordinates._getHeading(attributes) if hNum == nil then return '' end return tostring(hNum) end -- Helper core function for getHeading. function coordinates._getHeading(attributes) if attributes == nil then return nil end local hStr = string.match(mw.text.decode(attributes), 'heading:([^_]*)') if hStr == nil then return nil end local hNum = tonumber( hStr ) if hNum == nil then hStr = string.upper (hStr) hNum = compass_points[hStr] end if hNum ~= nil then hNum = hNum%360 end return hNum end --[[============================================================================ Convert degrees to degrees/minutes/seconds notation comonly used when displaying coordinates. Inputs: 1) latitude or longitude angle in degrees 2) georeference precission in degrees 3) language used in formating of the number ==============================================================================]] function coordinates.deg2dms(frame) local deg = tonumber(frame.args[1]) local degPrec = tonumber(frame.args[2]) or 0-- precision in degrees local lang if frame.args.lang and mw.language.isSupportedLanguage(frame.args.lang) then lang = frame.args.lang else -- get user's chosen language lang = mw.message.new( "lang" ):plain() end if deg==nil then return frame.args[1]; else return coordinates._deg2dms(deg, degPrec, lang) end end --[[============================================================================ Helper core function for deg2dms. deg2dms can be called by templates, while _deg2dms should be called from Lua. Inputs: * deg - positive coordinate in degrees * degPrec - coordinate precission in degrees will result in different angle format * lang - language to used when formating the number ==============================================================================]] function coordinates._deg2dms(deg, degPrec, lang) local dNum, mNum, sNum, dStr, mStr, sStr, formatStr, secPrec, c, k local Lang = mw.language.new(lang) -- adjust number display based on precission secPrec = degPrec*3600.0 -- coordinate precission in seconds if secPrec<0.05 then -- degPrec<1.3889e-05 formatStr = '%s° %s′ %s″' -- use DD° MM′ SS.SS″ format c = 360000 elseif secPrec<0.5 then -- 1.3889e-05<degPrec<1.3889e-04 formatStr = '%s° %s′ %s″' -- use DD° MM′ SS.S″ format c = 36000 elseif degPrec*60.0<0.5 then -- 1.3889e-04<degPrec<0.0083 formatStr = '%s° %s′ %s″' -- use DD° MM′ SS″ format c = 3600 elseif degPrec<0.5 then -- 0.0083<degPrec<0.5 formatStr = '%s° %s′' -- use DD° MM′ format c = 60 else -- if degPrec>0.5 then formatStr = '%s°' -- use DD° format c = 1 end -- create degree, minute and seconds numbers and string d = c/60 k = math.floor(c*(deg%360)+0.49) -- convert float to an integer. This step HAS to be identical for all conversions to avoid incorrect results due to different rounding dNum = math.floor(k/c) % 360 -- degree number (integer in 0-360 range) mNum = math.floor(k/d) % 60 -- minute number (integer in 0-60 range) sNum = 3600*(k%d) / c -- seconds number (float in 0-60 range with 0, 1 or 2 decimal digits) dStr = Lang:formatNum(dNum) -- degree string mStr = Lang:formatNum(mNum) -- minute string sStr = Lang:formatNum(sNum) -- second string if mNum<10 then mStr = '0' ..mStr -- pad with zero if a single digit end if sNum<10 then sStr = '0' ..sStr -- pad with zero if less than ten end return string.format(formatStr, dStr, mStr, sStr); end --[[============================================================================ Format coordinate location string, by creating and joining DMS strings for latutude and longitude. Also convert precission from meters to degrees. INPUTS: * lat = latitude in degrees * lon = longitude in degrees * lang = language code * prec = geolocation precission in meters ==============================================================================]] function coordinates.lat_lon(frame) local lat = tonumber(frame.args.lat) local lon = tonumber(frame.args.lon) local prec = math.abs(tonumber(frame.args.prec) or 0) -- location precision in meters if lon then -- get longitude t0 be in -180 to 180 range lon=lon%360 if lon>180 then lon = lon-360 end end local lang if frame.args.lang and mw.language.isSupportedLanguage(frame.args.lang) then lang = frame.args.lang else -- get user's chosen language lang = mw.message.new( "lang" ):plain() end if lat==nil or lon==nil then return NoLatLonString else local nsew = Fallback._langSwitch(i18n.NSEW, lang) -- find set of localized translation of N, S, W and E in the desired language local SN, EW, latStr, lonStr, lon2m, lat2m, phi if lat<0 then SN = nsew.S else SN = nsew.N end -- choose S or N depending on latitude degree sign if lon<0 then EW = nsew.W else EW = nsew.E end -- choose W or E depending on longitude degree sign lat2m=1 lon2m=1 if prec>0 then -- if user specified the precission of the geo location... phi = math.abs(lat)*math.pi/180 -- latitude in radiants lon2m = 6378137*math.cos(phi)*math.pi/180 -- see https://en.wikipedia.org/wiki/Longitude lat2m = 111000 -- average latitude degree size in meters end latStr = coordinates._deg2dms(math.abs(lat), prec/lat2m, lang) -- Convert latitude degrees to degrees/minutes/seconds lonStr = coordinates._deg2dms(math.abs(lon), prec/lon2m, lang) -- Convert longitude degrees to degrees/minutes/seconds return string.format('%s %s, %s %s', latStr, SN, lonStr, EW) --return string.format('<span class="latitude">%s %s</span>, <span class="longitude">%s %s</span>', latStr, SN, lonStr, EW) end end --[[============================================================================ Create URL for different sites. INPUTS: * site = Possinle sites: GeoHack, GoogleEarth, Proximityrama, OpenStreetMap, GoogleMaps (for Earth, Mars and Moon) * globe = Possible options: Earth, Mars or Moon. Venus, Mercury, Titan, Ganymede are also supported but are unused as of 2013. * lat = latitude string or number * lon = longitude string or number * lang = language code * attributes = attributes to be passed to GeoHack ==============================================================================]] function coordinates.externalLink(frame) args = frame.args if args.lang and mw.language.isSupportedLanguage(args.lang) then lang = args.lang else -- get user's chosen language lang = mw.message.new( "lang" ):plain() end local str = coordinates._externalLink(args.site or 'GeoHack', args.globe or 'Earth', args.lat, args.lon, lang, args.attributes or '') return frame:preprocess(str) end --[[============================================================================ Helper core function for externalLink. Create URL for different sites: INPUTS: * site = Possinle sites: GeoHack, GoogleEarth, Proximityrama, OpenStreetMap, GoogleMaps (for Earth, Mars and Moon) * globe = Possible options: Earth, Mars or Moon. Venus, Mercury, Titan, Ganymede are also supported but are unused as of 2013. * latStr = latitude string or number * lonStr = longitude string or number * lang = language code * attributes = attributes to be passed to GeoHack ==============================================================================]] function coordinates._externalLink(site, globe, latStr, lonStr, lang, attributes) local URLstr = SiteURL[site]; if site == 'GoogleMaps' then URLstr = SiteURL.GoogleMaps[globe] elseif site == 'GeoHack' then attributes = string.format('globe:%s_%s', globe, attributes) local pageName = mw.uri.encode( mw.title.getCurrentTitle().prefixedText, 'WIKI' ) pageName = mw.ustring.gsub( pageName, '%%', '%%%%') URLstr = mw.ustring.gsub( URLstr, '$attr', attributes) URLstr = mw.ustring.gsub( URLstr, '$page', pageName) URLstr = mw.ustring.gsub( URLstr, ' ', '_') end URLstr = mw.ustring.gsub( URLstr, '$lat' , latStr) URLstr = mw.ustring.gsub( URLstr, '$lon' , lonStr) URLstr = mw.ustring.gsub( URLstr, '$lang', lang) return URLstr end --[[============================================================================ Adjust GeoHack attributes depending on the template that calls it INPUTS: * attributes = attributes to be passed to GeoHack * mode = set by each calling template ==============================================================================]] function coordinates.alterAttributes(attributes, mode) -- indicate which template called it if mode=='camera' then -- Used by {{Location}} and {{Location dec}} if string.find(attributes, 'type:camera')==nil then attributes = 'type:camera_' .. attributes end elseif mode=='object'or mode =='globe' then -- Used by {{Object location}} if string.find(attributes, 'class:object')==nil then attributes = 'class:object_' .. attributes end elseif mode=='inline' then -- Used by {{Inline coordinates}} (actually that template does not set any attributes at the moment) elseif mode=='user' then -- Used by {{User location}} attributes = 'type:user_location' elseif mode=='institution' then --Used by {{Institution/coordinates}} (categories only) attributes = 'type:institution' end return attributes end --[[============================================================================ Create link to GeoHack tool which displays latitude and longitude coordinates in DMS format INPUTS: * globe = Possible options: Earth, Mars or Moon. Venus, Mercury, Titan, Ganymede are also supported but are unused as of 2013. * lat = latitude in degrees * lon = longitude in degrees * lang = language code * prec = geolocation precission in meters * attributes = attributes to be passed to GeoHack ==============================================================================]] function coordinates.GeoHack_link(frame) -- create link and coordintate string local latlon = coordinates.lat_lon(frame) if latlon==NoLatLonString then return latlon else frame.args.site = 'GeoHack' local url = coordinates.externalLink(frame) return string.format('<span class="plainlinksneverexpand">[%s %s]</span>', url, latlon) --<span class="plainlinks nourlexpansion"> end end --[[============================================================================ Create full external links section of {{Location}} or {{Object location}} templates, based on: * globe = Possible options: Earth, Mars or Moon. Venus, Mercury, Titan, Ganymede are also supported but are unused as of 2013. * mode = Possible options: - camera - call from {{location}} - object - call from {{Object location}} - globe - call from {{Globe location}} * lat = latitude in degrees * lon = longitude in degrees * lang = language code * namespace = namespace name: File, Category, (Gallery) ==============================================================================]] function coordinates.externalLinksSection(frame) args = frame.args if args.lang and mw.language.isSupportedLanguage(args.lang) then lang = args.lang else -- get user's chosen language lang = mw.message.new( "lang" ):plain() end if not args.namespace then args.namespace = mw.title.getCurrentTitle().namespace end local str if args.globe=='Earth' then -- Earth locations will have 3 or 4 links str = string.format('[%s %s] - [%s %s]', -- - [%s %s]', coordinates._externalLink('OpenStreetMap', 'Earth', args.lat, args.lon, lang, ''), Fallback._langSwitch(i18n.OpenStreetMaps, lang), -- GoogleMap link no longer works due to changes in the website software --coordinates._externalLink('GoogleMaps' , 'Earth', args.lat, args.lon, lang, ''), --Fallback._langSwitch(i18n.GoogleMaps, lang), coordinates._externalLink('GoogleEarth' , 'Earth', args.lat, args.lon, lang, ''), Fallback._langSwitch(i18n.GoogleEarth, lang)) if args.namespace=="Category" then str = string.format('%s - [%s %s]', str, coordinates._externalLink('Proximityrama', 'Earth', args.lat, args.lon, lang, ''), Fallback._langSwitch(i18n.Proximityrama, lang)) end elseif args.globe=='Mars' or args.globe=='Moon' then str = string.format('[%s %s]', coordinates._externalLink('GoogleMaps', args.globe, args.lat, args.lon, lang, ''), Fallback._langSwitch(i18n.GoogleMaps, lang)) end return frame:preprocess(str) -- use preprocess to expand {{#fullurl}} --return str end --[[============================================================================ Core section of template:Location, template:Object location and template:Globe location. This method requires several arguments to be passed to it or it's parent metchod/template: * globe = Possible options: Earth, Mars or Moon. Venus, Mercury, Titan, Ganymede are also supported but are unused as of 2013. * mode = Possible options: - camera - call from {{location}} - object - call from {{Object location}} - globe - call from {{Globe location}} * lat = latitude in degrees * lon = longitude in degrees * attributes = attributes * lang = language code * namespace = namespace: File, Category, Gallery * prec = geolocation precission in meters ==============================================================================]] function coordinates.LocationTemplateCore(frame) -- prepare arguments args = frame.args if not args or not args.lat then -- if no arguments provided than use parent arguments args = mw.getCurrentFrame():getParent().args end if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then args.lang = mw.message.new( "lang" ):plain() -- get user's chosen language end if not (args.namespace) then -- if namespace not provided than look it up args.namespace = mw.title.getCurrentTitle().namespace end if args.namespace=='' then -- if empty than it is a gallery args.namespace = 'Gallery' end local bare = yesno(args.bare,false) local Status = 'primary' -- used by {{#coordinates:}} if yesno(args.secondary,false) then Status = 'secondary' end args.attributes = coordinates.alterAttributes(args.attributes or '', args.mode) frame.args = args -- check for errors and add Geo (microformat) code for machine readability. local lat = tonumber(args.lat) local lon = tonumber(args.lon) if lon then -- get longitude t0 be in -180 to 180 range lon=lon%360 if lon>180 then lon = lon-360 end end local Categories, geoMicroFormat, coorTag = '', '', '' -- Categories, {{#coordinates}} and geoMicroFormat will be only added to File, Category and Gallery pages if (args.namespace == 'File' or args.namespace == 'Category' or args.namespace == 'Gallery') then if lat and lon then -- if lat and lon are numbers... if lat==0 and lon==0 then -- lat=0 and lon=0 is a common issue when copying from flickr and other sources Categories = CoorCat.default end if frame.args.attributes and string.find(frame.args.attributes, '=') then Categories = Categories .. CoorCat.attribute end if args.error=='1' or (math.abs(lat)>90) then -- check for errors ({{#coordinates:}} also checks for errors ) Categories = Categories .. CoorCat.erroneous end local cat = CoorCat[args.namespace] if cat then -- add category based on namespace Categories = Categories .. cat end -- if not earth than add a category for each globe if args.mode and args.globe and args.mode=='globe' and args.globe~='Earth' then Categories = Categories .. string.format(CoorCat[args.mode], args.globe) end -- add <span class="geo"> Geo (microformat) code: it is included for machine readability geoMicroFormat = string.format('<span class="geo" style="display:none">%10.6f; %11.6f</span>',lat, lon) -- add {{#coordinates}} tag, see https://www.mediawiki.org/wiki/Extension:GeoData if args.namespace == 'File' and Status == 'primary' and args.mode=='camera' then coorTag = string.format('{{#coordinates:primary|%10.6f|%11.6f|%s}}', lat, lon, args.attributes) end else -- if lat and lon are not numbers then add error category Categories = Categories .. CoorCat.erroneous end end -- Call helper functions to render different parts of the template local str1, str2, str3, str4, inner_table, heading str1 = coordinates.GeoHack_link(frame) -- the coordinates and link to GeoHack heading = coordinates._getHeading(frame.args.attributes) -- get heading arrow section if heading then --str1 = string.format('%s <span style="{{Transform-rotate|%f}}">[[File:North Pointer.svg|20px|link=|alt=]]</span>', str1, 360-heading) local fname = string.format('{{Compass rose file|%f|style=heading}}', heading) str1 = string.format('%s <span title="%s°">[[%s|25px|link=|alt=%s°]]</span>', str1, heading, fname, heading) end str2 = Fallback._langSwitch(i18n.LocationTemplateLinkLabel, args.lang) -- header of the link section str3 = coordinates.externalLinksSection(frame) or '' -- external link section str4 = string.format('[[File:Circle-information.svg|18x18px|alt=info|link=%s]]', Fallback._langSwitch(i18n.COM_GEO, args.lang) ) inner_table = string.format('<td style="border:none;">%s</td><td style="border:none;">%s %s</td><td style="border:none;">%s%s</td>', str1, str2, str3, str4, geoMicroFormat) -- combine strings into a table local templateText if bare then templateText = string.format('<table style="width:100%%"><tr>%s</tr></table>', inner_table) else -- choose name of the field local field_name = 'Location' if args.mode=='camera' then field_name = Fallback._langSwitch(i18n.CameraLocation, args.lang) elseif args.mode=='object' then field_name = Fallback._langSwitch(i18n.ObjectLocation, args.lang) elseif args.mode=='globe' then field_list = Fallback._langSwitch(i18n.GlobeLocation, args.lang) if args.globe and i18n.GlobeLocation['en'][args.globe] then -- verify globe is provided and is recognized field_name = field_list[args.globe] end end local style = frame:expandTemplate{ title="Infobar-Layout", args={ ["lang"] = lang, ["class"] = 'commons-file-information-table' } } templateText = string.format('<table lang="%s" %s><tr><th class="type fileinfo-paramfield">%s</th>%s</tr></table>', lang, style, field_name, inner_table) end return frame:preprocess(templateText .. Categories .. coorTag) end return coordinates