Module:Sandbox/Trappist the monk/Wiktionary

--[=[

Implement Template:Wiktionary.

Things that need doing: better error messaging [done] categorize: templates that use article title as (no parameters) templates that have  templates with terms that have without templates with errors special ISO 639-3 tags that are supported by ? mis – uncoded languages; not known to wiktionary mul – multiple languages; known to wiktionary as 'Translingual' und – undetermined; not known to wiktionary; used by this module to indicate the language of a without language tag prefix zxx – no linguistic content / not applicable; not known to wiktionary Wiktionary has List of languages, a wikitext list of language tags and their associated names. Not all of these tags appear in en:Module:Language/data. For example, these language tags are not in		Module:Language/data (as of 2023-12-13) but are in Wiktionary:List of languages: ca – Catalan nl – Dutch enm – Middle English fro – Old French There does not appear to be a mechanism that copies the appropriate data from Wiktionary to en.wiki so Module:Language/data grows organically; ugh. It may be necessary to extract a list of currently supported ISO 639-1 tags from wikt:Wiktionary:List_of_languages#Two-letter_codes to make sure that at the least those are part of Module:Language/data [list extracted from wikt:Module:languages/data/2 as Module:Sandbox/Trappist_the_monk/Wiktionary/data] Support language tag redirects in Module:Language/data [done] ]=]

require ('strict'); local local_wiki_tag = mw.language.getContentLanguage.code;					-- 'en' at enwiki

--[[--< E R R O R _ S I D E _ B O X >--

Return rendered side box with error message content. This function can likely go away if this or a similar module is adopted for creating the side box content.

]]

local function error_side_box (args_t, message, categories_t, frame) return frame:expandTemplate ({title = 'Sister project', args = {			-- render the template		position = args_t.position,												-- defaults to right		project = 'wiktionary',													-- to select appropriate image		text = string.format (' %s: %s ', ' error: ', message);															-- render the error message		}}) .. table.concat (categories_t);										-- with categories end

--[[--< S I D E _ B O X >--

Return rendered side box. This function can likely go away if this or a similar module is adopted for creating the side box content.

]]

local function side_box (args_t, items_t, categories_t, frame) local links_t = {};															-- holds a list of interwiki-linked terms for i, item_t in ipairs (items_t) do										-- build an interwiki link to wiktionary local title = item_t.term;												-- wiktionary article title if item_t.anchor then title = title .. item_t.anchor;										-- add a language-specific anchor if language tag or #anchor supplied in template call end links_t[i] = string.format ('%s',					-- create interwiki link for each individual term			(item_t.isSearch and "Special:Search/" or ""),			title,																-- wiktionary article title + anchor			item_t.lang_text													-- term wrapped in -provided markup	for display			); end local join1 = ', ';															-- create appropriate separators for the list of terms local join2 = #items_t > 2 and ', or ' or ' or ';

return frame:expandTemplate ({title = 'Sister project', args = {			-- render the template		position = args_t.position,												-- defaults to right		project = 'wiktionary',													-- to select appropriate image		text = string.format ('Look up %s in Wiktionary, the free dictionary.',	-- construct the text the goes inside the box mw.text.listToText (links_t, join1, join2)							-- concatenate the list of terms )		}}) .. table.concat (categories_t);										-- add categories end

--[[--< C A T E G O R Y _ A D D >--

returns nothing. Adds category wikilink to  if the template is used in mainspace

TODO: categorize templates that have without ? On initial implementation of this module, that would be every instance of the template so impractical at that time

]]

local added_cats_t = {};

local function category_add (category, categories_t) if not mw.title.getCurrentTitle:inNamespace (0) then						-- when not in mainspace return;																	-- abandon end if added_cats_t[category] then												-- when we've already added this category return;																	-- abandon end local category_names_t = {													-- a list of category names used by this module ['error'] = 'Wiktionary template errors', ['article title'] = 'Wiktionary template uses article title', ['anchor'] = 'Wiktionary template uses manual anchor', --	['no tag'] = 'Wiktionary template without language tag',				-- see TODO above }

table.insert (categories_t, table.concat ({									-- construct category wikilink '[[Category:',		category_names_t[category],		']]' }));

added_cats_t[category] = true;												-- remember that we've added this category to  end

--[[--< S E T _ A N C H O R >--

create a language-specific anchor (URI fragment) where the fragment is the wiktionary language name associated with the language tag prefixed to the 'term'.

]]

local function set_anchor (item_t) local wikt_lang_data = mw.loadData ('Module:Language/data');				-- load wikitionary supported languages list

if not item_t.anchor then if wikt_lang_data.redirects[item_t.tag] then item_t.tag = wikt_lang_data.redirects[item_t.tag]; end local data_t = wikt_lang_data.languages[item_t.tag];					-- primary wiktionary data source

local mw_lang_name;														-- holds MediaWiki name for language tag if not ({['mis'] = true, ['mul'] = true, ['zxx'] = true})[item_t.tag] then		-- these are supported by MediaWiki but have no value here mw_lang_name = mw.language.fetchLanguageName (item_t.tag, local_wiki_tag);	-- get MediaWiki's language name as fallback end if data_t and data_t.name then											-- if wiktionary has name for language tag ; not present for default tag 'und' item_t.anchor = mw.uri.anchorEncode ('#' .. data_t.name);			-- make an encoded anchor from the wiktionary language name so that it matches the language tag from the template call elseif mw_lang_name and (mw_lang_name ~= item_t.tag) and ('und' ~= item_t.tag) then	-- fetchLanguageName returns tag if tag not supported item_t.anchor = mw.uri.anchorEncode ('#' .. mw_lang_name);			-- make an encoded anchor from the MediaWiki language name so that it matches the language tag from the template call elseif 'und' ~= item_t.tag then											-- when neither wikitionary nor MediaWiki have a definition for  ('und' excepted) item_t.error = 'language tag "' .. item_t.tag .. '" is not known to wiktionary'; return;																-- abandon end end

if '' == item_t.anchor then													-- if anchor is set to empty string item_t.anchor = nil;													-- unset so we don't create a link with trailing '#' fragment marker end end

--[[--< M A I N >--

Return wikitext to display box.

]]

local function main (frame) local args_t = require ('Module:Arguments').getArgs (frame);

local items_t = {}; local categories_t = {}; local lang_mod = require ('Module:lang');									-- for direct access to the functions in Module:Lang local lang_text;															-- term and markup returned from Module:Lang.lang for _, arg in ipairs (args_t) do		arg = mw.text.trim (arg); if arg ~= '' then local tag, term, anchor; if arg:match ('^%a%a%a?:.+') then									-- does this arg have language tag prefix and a term? tag, term = arg:match ('^(%a%a%a?):(.*)');						-- yep, then extract them else term = arg;														-- nope, just a term end

if term:match ('.+#.+') then										-- does hav an anchor (URL fragment)? term, anchor = term:match ('(.+)(#.+)');						-- split the 'term#ancor' into and category_add ('anchor', categories_t);							-- add a category end table.insert (items_t, {tag = tag or 'und', term = term, anchor = anchor}); end end

if items_t[1] then for _, item_t in ipairs (items_t) do			local italic = (item_t.tag == local_wiki_tag) and 'yes' or nil;		-- local language same as language tag, italicize per words-as-words lang_text = lang_mod._lang ({item_t.tag, item_t.term, cat = 'no', italic = italic});		-- let control italics if lang_text:match ('class="error"') then category_add ('error', categories_t);							-- add a category return table.concat ({					error_side_box (args_t, 'language tag "' .. item_t.tag .. '" is not known to wikipedia', categories_t, frame),					(mw.title.getCurrentTitle:inNamespace (0) and ) or 				});																-- abandon with error message end item_t.lang_text = lang_text; set_anchor (item_t); if item_t.error then category_add ('error', categories_t);							-- add a category return table.concat ({											-- abandon with error message					error_side_box (args_t, item_t.error, categories_t, frame),					(mw.title.getCurrentTitle:inNamespace (0) and ) or 				});																-- abandon with error message end end else																		-- no terms supplied in template call so use article title local title = mw.ustring.lower(mw.title.getCurrentTitle.subpageText);	-- get the title; TODO: should we be setting page title to lowercase? lang_text = lang_mod._lang ({local_wiki_tag, title, cat = 'no', italic = 'yes'});	-- for consistency use for article title; italic per words-as-words items_t[1] = {term = title, lang_text = lang_text, isSearch = true };	-- don't break side box category_add ('article title', categories_t);							-- add a category end return side_box (args_t, items_t, categories_t, frame); end

----< E X P O R T E D  F U N C T I O N S >--

return { main = main }