Module:TNT

From Center for Integrated Circuits and Devices Research (CIDR)
Revision as of 20:43, 4 September 2022 by Louis Alarcon (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation for this module may be created at Module:TNT/doc

  1 --
  2 -- INTRO:   (!!! DO NOT RENAME THIS PAGE !!!)
  3 --    This module allows any template or module to be copy/pasted between
  4 --    wikis without any translation changes. All translation text is stored
  5 --    in the global  Data:*.tab  pages on Commons, and used everywhere.
  6 --
  7 -- SEE:   https://www.mediawiki.org/wiki/Multilingual_Templates_and_Modules
  8 --
  9 -- ATTENTION:
 10 --    Please do NOT rename this module - it has to be identical on all wikis.
 11 --    This code is maintained at https://www.mediawiki.org/wiki/Module:TNT
 12 --    Please do not modify it anywhere else, as it may get copied and override your changes.
 13 --    Suggestions can be made at https://www.mediawiki.org/wiki/Module_talk:TNT
 14 --
 15 -- DESCRIPTION:
 16 --    The "msg" function uses a Commons dataset to translate a message
 17 --    with a given key (e.g. source-table), plus optional arguments
 18 --    to the wiki markup in the current content language.
 19 --    Use lang=xx to set language.  Example:
 20 --
 21 --    {{#invoke:TNT | msg
 22 --     | I18n/Template:Graphs.tab  <!-- https://commons.wikimedia.org/wiki/Data:I18n/Template:Graphs.tab -->
 23 --     | source-table              <!-- uses a translation message with id = "source-table" -->
 24 --     | param1 }}                 <!-- optional parameter -->
 25 --
 26 --
 27 --    The "doc" function will generate the <templatedata> parameter documentation for templates.
 28 --    This way all template parameters can be stored and localized in a single Commons dataset.
 29 --    NOTE: "doc" assumes that all documentation is located in Data:Templatedata/* on Commons.
 30 --
 31 --    {{#invoke:TNT | doc | Graph:Lines }}
 32 --        uses https://commons.wikimedia.org/wiki/Data:Templatedata/Graph:Lines.tab
 33 --        if the current page is Template:Graph:Lines/doc
 34 --
 35 
 36 local p = {}
 37 local i18nDataset = 'I18n/Module:TNT.tab'
 38 
 39 -- Forward declaration of the local functions
 40 local sanitizeDataset, loadData, link, formatMessage
 41 
 42 function p.msg(frame)
 43 	local dataset, id
 44 	local params = {}
 45 	local lang = nil
 46 	for k, v in pairs(frame.args) do
 47 		if k == 1 then
 48 			dataset = mw.text.trim(v)
 49 		elseif k == 2 then
 50 			id = mw.text.trim(v)
 51 		elseif type(k) == 'number' then
 52 			table.insert(params, mw.text.trim(v))
 53 		elseif k == 'lang' and v ~= '_' then
 54 			lang = mw.text.trim(v)
 55 		end
 56 	end
 57 	return formatMessage(dataset, id, params, lang)
 58 end
 59 
 60 -- Identical to p.msg() above, but used from other lua modules
 61 -- Parameters:  name of dataset, message key, optional arguments
 62 -- Example with 2 params:  format('I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset')
 63 function p.format(dataset, key, ...)
 64 	local checkType = require('libraryUtil').checkType
 65 	checkType('format', 1, dataset, 'string')
 66 	checkType('format', 2, key, 'string')
 67 	return formatMessage(dataset, key, {...})
 68 end
 69 
 70 
 71 -- Identical to p.msg() above, but used from other lua modules with the language param
 72 -- Parameters:  language code, name of dataset, message key, optional arguments
 73 -- Example with 2 params:  formatInLanguage('es', I18n/Module:TNT', 'error_bad_msgkey', 'my-key', 'my-dataset')
 74 function p.formatInLanguage(lang, dataset, key, ...)
 75 	local checkType = require('libraryUtil').checkType
 76 	checkType('formatInLanguage', 1, lang, 'string')
 77 	checkType('formatInLanguage', 2, dataset, 'string')
 78 	checkType('formatInLanguage', 3, key, 'string')
 79 	return formatMessage(dataset, key, {...}, lang)
 80 end
 81 
 82 -- Obsolete function that adds a 'c:' prefix to the first param.
 83 -- "Sandbox/Sample.tab" -> 'c:Data:Sandbox/Sample.tab'
 84 function p.link(frame)
 85 	return link(frame.args[1])
 86 end
 87 
 88 function p.doc(frame)
 89 	local dataset = 'Templatedata/' .. sanitizeDataset(frame.args[1])
 90 	return frame:extensionTag('templatedata', p.getTemplateData(dataset)) ..
 91 		   formatMessage(i18nDataset, 'edit_doc', {link(dataset)})
 92 end
 93 
 94 function p.getTemplateData(dataset)
 95 	-- TODO: add '_' parameter once lua starts reindexing properly for "all" languages
 96 	local data = loadData(dataset)
 97 	local names = {}
 98 	for _, field in pairs(data.schema.fields) do
 99 		table.insert(names, field.name)
100 	end
101 
102 	local params = {}
103 	local paramOrder = {}
104 	for _, row in pairs(data.data) do
105 		local newVal = {}
106 		local name = nil
107 		for pos, val in pairs(row) do
108 			local columnName = names[pos]
109 			if columnName == 'name' then
110 				name = val
111 			else
112 				newVal[columnName] = val
113 			end
114 		end
115 		if name then
116 			params[name] = newVal
117 			table.insert(paramOrder, name)
118 		end
119 	end
120 
121 	-- Work around json encoding treating {"1":{...}} as an [{...}]
122 	params['zzz123']=''
123 
124 	local json = mw.text.jsonEncode({
125 		params=params,
126 		paramOrder=paramOrder,
127 		description=data.description
128 	})
129 
130 	json = string.gsub(json,'"zzz123":"",?', "")
131 
132 	return json
133 end
134 
135 -- Local functions
136 
137 sanitizeDataset = function(dataset)
138 	if not dataset then
139 		return nil
140 	end
141 	dataset = mw.text.trim(dataset)
142 	if dataset == '' then
143 		return nil
144 	elseif string.sub(dataset,-4) ~= '.tab' then
145 		return dataset .. '.tab'
146 	else
147 		return dataset
148 	end
149 end
150 
151 loadData = function(dataset, lang)
152 	dataset = sanitizeDataset(dataset)
153 	if not dataset then
154 		error(formatMessage(i18nDataset, 'error_no_dataset', {}))
155 	end
156 
157 	-- Give helpful error to thirdparties who try and copy this module.
158 	if not mw.ext or not mw.ext.data or not mw.ext.data.get then
159 		error('Missing JsonConfig extension; Cannot load https://commons.wikimedia.org/wiki/Data:' .. dataset)
160 	end
161 
162 	local data = mw.ext.data.get(dataset, lang)
163 
164 	if data == false then
165 		if dataset == i18nDataset then
166 			-- Prevent cyclical calls
167 			error('Missing Commons dataset ' .. i18nDataset)
168 		else
169 			error(formatMessage(i18nDataset, 'error_bad_dataset', {link(dataset)}))
170 		end
171 	end
172 	return data
173 end
174 
175 -- Given a dataset name, convert it to a title with the 'commons:data:' prefix
176 link = function(dataset)
177 	return 'c:Data:' .. mw.text.trim(dataset or '')
178 end
179 
180 formatMessage = function(dataset, key, params, lang)
181 	for _, row in pairs(loadData(dataset, lang).data) do
182 		local id, msg = unpack(row)
183 		if id == key then
184 			local result = mw.message.newRawMessage(msg, unpack(params or {}))
185 			return result:plain()
186 		end
187 	end
188 	if dataset == i18nDataset then
189 		-- Prevent cyclical calls
190 		error('Invalid message key "' .. key .. '"')
191 	else
192 		error(formatMessage(i18nDataset, 'error_bad_msgkey', {key, link(dataset)}))
193 	end
194 end
195 
196 return p