Модуль:Tr/loaddata

Материал из Infernum Mod Wiki
Перейти к навигации Перейти к поиску
Lua.svg Документация Документация, указанная ниже, находится на странице «Модуль:Tr/loaddata/doc». (править | история)

This module is used by Module:Tr to fetch the translation database for a language. To improve performance, the translation databases are not fetched every time Module:Tr is invoked, but are cached instead. This module returns that cache. It is called from the language-specific loaders (Модуль:Tr/loaddata-en, Модуль:Tr/loaddata-ru, etc., which in turn are called directly by Module:Tr) with the following function:

  • require('Module:Tr/loaddata').load('<language>')
Returns the cache of the translation database for the given language (Модуль:Tr/db-en, Модуль:Tr/db-ru, etc.). In addition to the three tables main, pagename, and reversed, the returned table has a lookup table onWikiLangList in which all on-wiki languages are true.

Caching the translation databases means that changes to them are not immediately reflected. The cache must be cleared ("purged") in order for the changes to take effect. When the cache is purged, this module will recreate it. The cache can be purged from another module with the following function. This function is only intended to be called by Module:Tr – to purge it manually, invoke that module.

  • require('Module:Tr/loaddata').purge('<language>')
Purges the cache of the translation database for the given language. The cache will be recreated with the most recent version of the translation database the next time the load function is called.

--------------------------------------------------------------------------------
--
-- =============================================================================
--
-- Module:Tr/loaddata
--
-- Cache management of the translation databases for Module:Tr
--
-- =============================================================================
--
-- Code annotations:
-- This module is documented according to LuaCATS (Lua Comment and Type System).
-- LuaCATS comments are prefixed with three dashes (---) and use Markdown syntax.
-- For a full list of annotations, see the following link:
-- https://luals.github.io/wiki/annotations/
--
--------------------------------------------------------------------------------


local cache = mw.ext.LuaCache
local trim = mw.text.trim

-- Note:
-- It seems that objects/lists stored via LuaCache have a limit on the number of
-- entities, which is about 8000. Any object/list with more than 8000 entities or
-- with such a large sub-object/sub-list will be truncated. Therefore, we encode
-- the data into a JSON string to get around this problem.

--------------------------------------------------------------------------------
---Main return object
local p = {}

---Get the cached translation database for the specified language `lang`. Recreate
---the cache if necessary.
---This function should only be called from the `Module:Tr/loaddata-<lang>` modules
---(e.g. `Module:Tr/loaddata-ar`), like so: `return require('Module:Tr/loaddata').load('<lang>')`
---@param lang string Language code
---@return table<string, string> data
p.load = function(lang)
	-- attempt to load the cached data
	local success, result = pcall(function()
		return mw.text.jsonDecode(cache.get('tr__database-' .. lang))
	end)
	if success then
		-- cached data is available, just return it
		return result
	end

	-- cached data is not available, so we need to recreate it

	---Fetch the database. We use `require()` for this and not `mw.loadData()`
	---because the return table of `mw.loadData()` has a metatable and therefore
	---cannot be used with `cache.set()` and `mw.loadData()`.
	---@type table
	local info = {}
	info.mod = require('Module:Tr/db-' .. lang)

	---List of language codes that are "on-wiki", i.e. not on a separate wiki. See
	---[[Template:LangList]].
	---@type { [string]: true }
	info.onWikiLangList = {}
	local langListStr = mw.getCurrentFrame():expandTemplate{ title = 'langList', args = {'onWiki'} }
	-- convert e.g. `"ar, bg, cs, da"` to `{"ar", " bg", " cs", " da"}`, then to
	-- `{["ar"] = true, ["bg"] = true, ["cs"] = true, ["da"] = true}`
	for _, langcode in ipairs(mw.text.split(langListStr, ',')) do
		local _lcode = trim(langcode)
		if _lcode and _lcode ~= '' then
			info.onWikiLangList[trim(langcode)] = true
		end
	end

	---Assemble the database for "reverse" translation (local language to English).
	---@type table<string, string>
	local reversed = {}
	-- add all terms from the `main` table
	for termEnglish, termLocalLanguage in pairs(info.mod.main or {}) do
		reversed[termLocalLanguage] = termEnglish
	end
	-- add all terms from the `pagename` table, potentially overriding the `main`
	-- table where necessary
	for termEnglish, termLocalLanguage in pairs(info.mod.pagename or {}) do
		reversed[termLocalLanguage] = termEnglish
	end
	-- add all manually specified terms, potentially overriding any terms from
	-- `main` and `pagename` tables
	for termLocalLanguage, termEnglish in pairs(info.mod.reversed or {}) do
		reversed[termLocalLanguage] = termEnglish
	end
	-- for on-wiki languages: the translation `<English page>/<lang>` => `<English page>`
	-- is handled by {{pagename2en}}, so there's no need to add that to this database
	info.mod.reversed = reversed
	
	-- repeat the same for vanilla DB
	info.vanilla = require('Module:Tr/vanilla-' .. lang)
	---Assemble the database for "reverse" translation (local language to English).
	---@type table<string, string>
	local reversed_v = {}
	-- add all terms from the `main` table
	for termEnglish, termLocalLanguage in pairs(info.vanilla.main or {}) do
		reversed_v[termLocalLanguage] = termEnglish
	end
	-- add all terms from the `pagename` table, potentially overriding the `main`
	-- table where necessary
	for termEnglish, termLocalLanguage in pairs(info.vanilla.pagename or {}) do
		reversed_v[termLocalLanguage] = termEnglish
	end
	-- add all manually specified terms, potentially overriding any terms from
	-- `main` and `pagename` tables
	for termLocalLanguage, termEnglish in pairs(info.vanilla.reversed or {}) do
		reversed_v[termLocalLanguage] = termEnglish
	end
	-- for on-wiki languages: the translation `<English page>/<lang>` => `<English page>`
	-- is handled by {{pagename2en}}, so there's no need to add that to this database
	info.vanilla.reversed = reversed_v

	-- cache the `info` table
	cache.set('tr__database-' .. lang, mw.text.jsonEncode(info))
	return info
end  -- p.load

---Purge the translation database for the specified language `<lang>`. When the
---`load` function is called the next time, the database cache will be forcefully
---recreated.
---This function should only be called from the `purge` function of `Module:Tr`.
---That function can be invoked from wikitext via `{{#invoke:Tr|purge|lang=<lang>}}`,
---which is done on each `Module:Tr/db-<lang>/doc` page. So purging that documentation
---page (or the module page `Module:Tr/db-<lang>` itself) will call this function
---and purge the respective language's translation database cache.
---@param lang string Language code
p.purge = function(lang)
	cache.delete('tr__database-' .. lang)
end  -- p.purge

return p