Module:Element

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Edit] [Purge] Documentation
Dialog-warning-orange.svg Note: This template is used on a lot of pages. In order not to put too much load on the servers, edits should be kept to a bare minimum.
Please discuss proposed changes on the talk page first.
Editing a template causes all pages that use the template to be re-rendered. If the Template is used often, this can put a lot of load on the servers since it fills up the job queue. [statistics]

This page documents the features of the templates {{Area}}, {{Node}}, {{Relation}}, and {{Way}}. These templates can be used for inserting links to either nodes, ways, or relations (area links to a closed way) as well as tool links. All templates share a common codebase. Therefore, they work almost identical ({{Area}} and {{Relation}} have each a minor difference to the rest).
It was rewritten in Autumn 2018 using fewer options and Lua.

Usage

The usage is similar for all templates described here. You just have to adjust the name (e.g. {{Area|...}} instead of {{Node|...}}). Writing

{{node|12345}}

results in

node 12345

Overview of all parameters:

Name/Number Possible values Description
1 Integer refers to an OSM ID, required parameter
2 String label for the main link, default: same as ID
tools all, josm, mini, no, or short tool links to be displayed, default: no(ne)
lang language code from Mediawiki's list or special code in this wiki used to assure the labelling of the links in a certain language (see section Translation below)

Feature list

Wiki code Result Note
{{Relation|2345}} relation 2345 The icon links to the wiki article about relations.
{{Relation|2345|Promenade}} relation Promenade
{{Relation|2345|tools= all }} relation 2345 (iD JOSM Potlatch2 history analyse)
{{Relation|2345|tools= all |Promenade}} relation Promenade (iD JOSM Potlatch2 history analyse)
{{Relation|2345|tools= all |lang= vi }} relation 2345 (iD JOSM Potlatch2 lịch sử phân tích) translation to Vietnamese
{{Relation|2345|Promenade|tools= all |lang= ar }} relation Promenade (iD JOSM Potlatch2 التاريخ analyse) Help translate this to Arabic translation falls back to English as Arabic translation is incomplete.
{{Way|12346|tools= all |lang= ar }} way 12346 (iD JOSM Potlatch2 التاريخ) links displayed depending on the element
{{Relation|2345|tools= josm }} relation 2345 (JOSM)
{{Relation|2345|tools= josm |Promenade}} relation Promenade (JOSM)
{{Relation|2345|tools= mini }} 2345
{{Relation|2345|tools= mini |Promenade}} Promenade
{{Relation|2345|tools= no }} relation 2345
{{Relation|2345|tools= no |Promenade}} relation Promenade
{{Relation|2345|tools= short }} 2345 (i J P2)
{{Relation|2345|tools= short |Promenade}} Promenade (i J P2)
{{Relation||Promenade}} Lua error in Module:Element at line 60: Given relation id parameter is not a number. Does not work, ID required.

Translation

If the parameter tools is set to all, the link labelled history will be shown. In case of {{Relation}} there is an additional link analyse. Their labels will align themselves to the page language. There is also a lang parameter for explicitly setting the language. Extracting the language of a page seems to be an expensive process (for the parser which takes longer to create the page). Unfortunately, this is also repeated for every occurrence of the template even on the same page. Therefore, translations are limited to a minimum (i.e. there is a translation with tools=all only).

lang parameter

The lang parameter is used to explicitly request a translated version of the template. It translates two English texts ("analyse" and "history"). These are used with the setting tools=all only. It also adds the prefix for the link to the article "relation" (below the icon) regardless of its existence. Whilst the language is automatically detected, the link will not change without request. This is due to the fact that the icon's wikicode is generated before the language version may be detected.

Languages for Translation

The module stores all translations in Module:Element/translation. There are the following priorities for examining the correct language:

  1. user input in lang parameter
  2. dedicated language namespace (DE, ES, FR, IT, JA, NL, RU)
  3. language title prefix (all other prefixes)
  4. English as default

This means that there is no specified fallback language used apart from English.
The templates {{Hu:Relation}}, {{Pl:Relation}} and {{Pt:Relation}} are versions of this template which fall back to Hungarian, Polish and Portuguese if no user input is provided.

Adding a Language

Please paste the following lines into the code of Module:Element/translation:

 translateAnalyse = {
 	-- other language codes alphabetically before 'code'
 	['code'] = "your translation",
 	-- other language codes alphabetically after 'code'
 },
 translateHistory = {
 	-- other language codes alphabetically before 'code'
 	['code'] = "your translation",
 	-- other language codes alphabetically after 'code'
 },

Missing language

If there is no complete translation, the page is also added to one of the subcategories of Category:Pages with missing translation. This is useful for finding missing translations in this wiki. The language name is read from Module:OSM Constants or mw.language.fetchLanguageName(pageLanguage, 'en').

Design Decisions

This section aims to explain why this template works this way. It should be read before proposing any changes. There may be different opinions (see Discussion page), but this documentation only focuses on the current implementation.

Why are the tools not shown by default?
This is simply too "expensive" (see translation). This setting would result in many pages being displayed in maintenance categories like Category:Pages where template include size is exceeded. It would also assume that everyone using this template (think of a mapper fixing a wiki error without wiki background) wants to have all tools available.
Why are there so few tools only?
This is a general purpose template, if you need special links, you can add them directly to your page. Please remember that the parser is not able to cache this template, so if you link to five relations, it has to create 35 (= 5 * 7) links in the worst case (i.e. displaying all tools).
Why was the "undefined relation" option dropped?
Simply because it fails its purpose: This template is for linking to a relation, if there is no relation (yet) you can simply leave out this template (this is commonly done now anyway). This would be like a link to a web page with an "under construction" banner only. In addition, as it displayed text, it had to compute the page language and translate the text for every call, a functionality that can be archived at lower cost by inserting the text itself.
Why is there no "status"?
Template:State provides a more detailed way of documenting mapping statuses.
Why are shortened URLs used instead of the long forms?
There are pages that include this template over 1000 times. Replacing short URLs like osm.org with openstreetmap.org would increase the size of the expanded text by 11 characters. The change would scale up to 11,000 characters in such an article. There are also options which use multiple links, this would result in an even bigger increase.


  1 --[[ Please remember to use the talk page before changing this template! 
  2 	 When the first Lua version was written this was used on more than 5000 pages,
  3 	 now it is probably some 3000 more. 
  4 	 A change will cause a re-rendering of all pages. Keep that in mind! ]]--
  5 
  6 local p = {}
  7 local translations = mw.loadData('Module:Element/translation')
  8 
  9 -- start for Template:Area
 10 function p.area(frame)
 11 	-- extracting arguments
 12 	local areaId = frame.args[1]
 13 	local areaName = frame.args[2]
 14 	local toolbarSetting = frame.args["tools"]
 15 	local langcodeInput = frame.args["lang"]
 16 	
 17 	-- checking for correct parameters
 18 	assert(tonumber(areaId), "Given way id parameter is not a number")
 19 	if areaName == "" then
 20 		areaName = nil
 21 	elseif areaName ~= nil then
 22 		areaName = mw.text.trim(areaName)
 23 	end
 24 	areaId = mw.text.trim(areaId)
 25 	if langcodeInput ~= nil then langcodeInput = string.lower(langcodeInput) end
 26 	
 27 	return elementText("area", areaId, areaName, toolbarSetting, langcodeInput)
 28 end
 29 
 30 -- start for Template:Node
 31 function p.node(frame)
 32 	-- extracting arguments
 33 	local nodeId = frame.args[1]
 34 	local nodeName = frame.args[2]
 35 	local toolbarSetting = frame.args["tools"]
 36 	local langcodeInput = frame.args["lang"]
 37 	
 38 	-- checking for correct parameters
 39 	assert(tonumber(nodeId), "Given node id parameter is not a number")
 40 	if nodeName == "" then
 41 		nodeName = nil 
 42 	elseif nodeName ~= nil then
 43 		nodeName = mw.text.trim(nodeName)
 44 	end
 45 	nodeId = mw.text.trim(nodeId)
 46 	if langcodeInput ~= nil then langcodeInput = string.lower(langcodeInput) end
 47 	
 48 	return elementText("node", nodeId, nodeName, toolbarSetting, langcodeInput)
 49 end
 50 
 51 -- start for Template:Relation
 52 function p.relation(frame)
 53 	-- extracting arguments
 54 	local relationId = frame.args[1]
 55 	local relationName = frame.args[2]
 56 	local toolbarSetting = frame.args["tools"]
 57 	local langcodeInput = frame.args["lang"]
 58 	
 59 	-- checking for correct parameters
 60 	assert(tonumber(relationId), "Given relation id parameter is not a number")
 61 	if relationName == "" then
 62 		relationName = nil 
 63 	elseif relationName ~= nil then
 64 		relationName = mw.text.trim(relationName)
 65 	end
 66 	relationId = mw.text.trim(relationId)
 67 	if langcodeInput ~= nil then langcodeInput = string.lower(langcodeInput) end
 68 	
 69 	return elementText("relation", relationId, relationName, toolbarSetting, langcodeInput)
 70 end
 71 
 72 -- start for Template:Way
 73 function p.way(frame)
 74 	-- extracting arguments
 75 	local wayId = frame.args[1]
 76 	local wayName = frame.args[2]
 77 	local toolbarSetting = frame.args["tools"]
 78 	local langcodeInput = frame.args["lang"]
 79 	
 80 	-- checking for correct parameters
 81 	assert(tonumber(wayId), "Given way id parameter is not a number")
 82 	if wayName == "" then
 83 		wayName = nil 
 84 	elseif wayName ~= nil then
 85 		wayName = mw.text.trim(wayName)
 86 	end
 87 	wayId = mw.text.trim(wayId)
 88 	if langcodeInput ~= nil then langcodeInput = string.lower(langcodeInput) end
 89 	
 90 	return elementText("way", wayId, wayName, toolbarSetting, langcodeInput)
 91 end
 92 
 93 -- Main function compiling the wiki text
 94 function elementText(elementType, elementId, elementName, toolbarSetting, langcodeInput)
 95 	local output = {}
 96 	local elementDescription = elementType
 97 	if elementType == "area" then elementType = "way" end -- non-existing area type
 98 	
 99 	output[1] = '<span class="plainlinks"><bdi class="sortkey" style="display:none;speak:none">'
100     if elementName == nil then
101         output[2] = elementId
102     else
103         output[2] = elementName
104     end
105 	output[3] = '</bdi>'
106 	
107 	if(toolbarSetting == "mini") then 
108 		output[4] = '[//osm.org/' .. elementType ..'/' .. elementId
109 		if elementName == nil then
110 			output[5] = '<span title="browse ' .. elementDescription .. '">' .. elementId
111 		else
112 			output[5] = '<span title="browse ' .. elementDescription .. ' ' .. elementId
113 			 .. '">' .. elementName
114 		end
115 		output[6] = '</span>]'
116 	
117 	elseif (toolbarSetting == "short") then
118 		output[4] = '<small>[//osm.org/' .. elementType .. '/' .. elementId
119 		if elementName == nil then
120 			output[5] = '<span title="browse ' .. elementDescription .. '">' .. elementId
121 		else
122 			output[5] = '<span title="browse ' .. elementDescription .. ' ' .. elementId
123 			 .. '">' .. elementName
124 		end
125 		output[6] = '</span>]&nbsp;<tt class="noprint" style="background:#EEF">(' ..
126 			'[//osm.org/edit?editor=id&' .. elementType .. '=' .. elementId .. 
127 			'<span title="iD">i</span>]&nbsp;'
128 		output[7] = '[http://localhost:8111/import?url=https://api.osm.org/api/0.6/'
129 			 .. elementType .. '/' .. elementId .. '/full <span title="JOSM">J</span>]&nbsp;'
130 		output[8] = '[//osm.org/edit?editor=potlatch2&zoom=11&' .. elementType .. '='
131 			 .. elementId .. ' <span title="Potlatch2">P2</span>]'
132 		output[9] = ')</tt></small>'
133 	
134 	else
135 		output[4] = '[[File:Osm element ' .. elementDescription .. '.svg|20px|link='
136 		if langcodeInput ~= nil and langcodeInput ~= 'en' then
137 			output[5] = langcodeInput .. ':' .. string.upper(string.sub(elementDescription, 1, 1))
138 				 .. string.sub(elementDescription, 2, -1)
139 			--[[ no case distinction in page namespaces, 
140 				no check for page existance for the sake of faster processing ]]--
141 		else
142 			output[5] = elementDescription
143 		end
144 		output[6] = '|' .. elementDescription .. ']]&nbsp;'
145 		output[7] = '[//osm.org/' .. elementType .. '/' .. elementId
146 			.. ' <span title="browse '.. elementDescription
147 		if elementName == nil then
148 			output[8] = '">' .. elementId
149 		else
150 			output[8] = ' ' .. elementId .. '">' .. elementName
151 		end
152 		output[9] = '</span>]'
153 		
154 		if toolbarSetting == "all" then
155 			local pageLanguage = langcode(langcodeInput)
156 			local translationComplete = true
157 			local transHistory = translations.translateHistory[pageLanguage]
158 			if not transHistory then
159 				translationComplete = false
160 				transHistory = translations.translateHistory['en']
161 			end
162 			
163 			output[10] = ' <small>([//osm.org/edit?editor=id&' 
164 				 .. elementType .. '=' .. elementId .. ' iD] '
165 			output[11] = '[http://localhost:8111/import?url=https://api.osm.org/api/0.6/'
166 				 .. elementType .. '/' .. elementId .. '/full JOSM] '
167 			output[12] = '[//osm.org/edit?editor=potlatch2&zoom=11&'
168 				 .. elementType .. '=' .. elementId .. ' Potlatch2] '
169 			output[13] = '[http://osm.virtuelle-loipe.de/history/?type='
170 				 .. elementType .. '&ref=' .. elementId .. ' ' .. transHistory .. ']'
171 			if elementType == 'relation' then -- relation analysis
172 				local transAnalyse = translations.translateAnalyse[pageLanguage]
173 				if not transAnalyse then
174 					translationComplete = false
175 					transAnalyse = translations.translateAnalyse['en']
176 				end
177 				output[14] = ' [http://ra.osmsurround.org/analyze.jsp?relationId='
178 					.. elementId .. ' ' .. transAnalyse ..']'
179 			end
180 			table.insert(output, ')</small>')
181 			if not translationComplete then
182 				local fullEnglishName = languageName(pageLanguage)
183 				if string.len(fullEnglishName) ~= 0 then
184 					table.insert(output, '[[Category:Pages unavailable in '
185 						.. fullEnglishName .. ']] [[File:Translate.svg|x10px|link='
186 						.. 'Module:Element#Adding_a_Language|Help translate this to '
187 						.. fullEnglishName .. ']]')
188 				end
189 			end
190 
191 		elseif toolbarSetting == "josm" then
192 			output[10] = ' <small>([http://localhost:8111/import?url='
193 				 .. 'https://api.openstreetmap.org/api/0.6/' .. elementType
194 			output[11] = '/' .. elementId .. '/full JOSM])</small>'
195 		end
196 	end
197 	
198 	table.insert(output, "</span>") -- ends class plainlinks
199 	return tostring(table.concat(output))
200 end
201 
202 -- this uses the external module 'OsmPageTitleParser': 
203 function langcode(langcodeInput)
204 	--[[ Priorities:
205 		1 user input
206 		2 dedicated language namespace
207 		3 language title prefix
208 		4 'en' as default
209 	]]--
210 
211 	if langcodeInput then
212 		return string.lower(langcodeInput)
213 	end
214 
215 	local langModule = require('Module:OsmPageTitleParser')
216 	return tostring((langModule.parseTitle(mw.title.getCurrentTitle()).language):getCode())
217 end
218 
219 function languageName(code)
220 	local constantsModule = mw.loadData('Module:OSM Constants')
221 	-- should be already loaded (needed by OsmPageTitleParser as well)
222 	local customLangName = constantsModule.customLangCodes[code]
223 	
224 	if customLangName ~= nil then
225 		return customLangName
226 	else
227 		return mw.language.fetchLanguageName(code, 'en')
228 	end
229 end
230 	
231 return p