Module:Project I18n
Jump to navigation
Jump to search
Template:Docbunto
Subpages
Template:-
-- <nowiki>
---
-- I18n report module for Dev Wiki.
-- @module p
-- @version 0.5.2
-- @author [[User:KockaAdmiralac|KockaAdmiralac]]
-- @author [[User:Speedit|Speedit]]
-- @release stable
-- @todo Standardise {{T|LangSelect}} so that parameters work.
local p = {}
-- Module dependencies.
local yesno = require('Module:Yesno')
require('Module:No interwiki access')
-- Module variables.
-- @section vars
local languages = {
'ar',
'bg',
'ca',
'cs',
'da',
'de',
'el',
'es',
'et',
'fa',
'fi',
'fr',
'he',
'hi',
'hr',
'hu',
'id',
'it',
'ja',
'ko',
'ms',
'nl',
'no',
'pl',
'pt-br',
'ro',
'ru',
'sr-ec',
'sr-el',
'sv',
'th',
'tl',
'tr',
'uk',
'vi',
'zh-hans',
'zh-hant'
}
local nonscripts = {
['MediaWiki:FANDOM-Monaco/code.js'] = true,
['MediaWiki:I18nEdit/code.js'] = true,
['MediaWiki:I18nEditTests/code.js'] = true
}
local title = mw.title.getCurrentTitle()
-- Module utilities.
local function selectLang(frame)
local selected = frame.preprocess
and frame:preprocess('{{int:lang}}')
or mw.getContentLanguage():getCode()
for i, lang in ipairs(languages) do
supported = supported and true or lang == selected
end
selected = supported and selected or 'pl'
return selected
end
local function padright(str, len, char)
char = char or ' '
return str .. string.rep(char, len - #str)
end
-- Package functions.
-- Language list generator.
-- @param {table} frame Frame table from invocation.
-- @return {string} list List of languages as <ul>
-- @see p.main
function p.langs(frame)
local selected = selectLang(frame)
local uri = mw.uri.fullUrl(title.prefixedText, { uselang = selected })
local list = mw.html.create('ul')
:addClass('template-documentation-langs')
:css('flex', '0 0 auto')
:tag('li'):addClass('selected')
:wikitext('[' .. tostring(uri) .. ' ' .. mw.language.fetchLanguageName(selected) .. ']')
:done()
for i, lang in ipairs(languages) do
uri:extend({ uselang = lang })
uri.fragment = frame.args[3]
if lang ~= selected then
list:tag('li')
:wikitext('[' .. tostring(uri) .. ' ' .. mw.language.fetchLanguageName(lang) .. ']')
end
end
list = tostring(list)
return frame
and frame:preprocess(list)
or mw.text.nowiki(list)
end
-- Untranslated JS report.
-- @param {table} frame Frame table from invocation.
-- @return {string} report List of untranslated scripts
-- @see p.main
function p.scripts(frame)
local selected = selectLang(frame)
local name = mw.language.fetchLanguageName(selected)
local report = frame:preprocess(table.concat({
'{{#dpl:',
'| allowcachedresults = 1',
'| namespace = 0',
'| category = Scripts using I18n-js',
'| notcategory = Translated scripts/', name,
'| notcategory = Archived',
'| format = ,\\n* [[%TITLE%]] ([[Special:BlankPage/I18nEdit/%TITLE%/', selected .. '|translate]]),,',
'| noresultsheader = ²{int:wikiasearch2-noresults}²',
'}}'
}))
return report
end
-- Untranslated documentation report.
-- @param {table} frame Frame table from invocation.
-- @return {string} report List of untranslated documentation
-- @see p.main
function p.pages(frame)
local selected = selectLang(frame)
local report = frame:preprocess(table.concat({
'{{#dpl:',
'| allowcachedresults = 1',
'| namespace = 0',
'| nottitleregexp = /',
'| format = ,²{#ifeq:²{#dpl:¦title = %PAGE%/', selected,
'¦ noresultsheader = no}²¦no¦* [[%PAGE%]]\n}²,,',
'| categoryregexp = JavaScript¦CSS',
'| notcategory = Archived',
'| noresultsheader = <nowiki />',
'}}'
}))
return report
end
-- Partially translated documentation report.
-- @param {table} frame Frame table from invocation.
-- @return {string} report List of all partially translated docs
-- @see p.main
function p.partials(frame)
local report = frame:preprocess(table.concat({
'{{#dpl:',
'| allowcachedresults = 1',
'| category = Please translate',
'| nottitlematch = Maintenance/Dummy page',
'| noresultsheader = There are no articles with {{t|Untranslated}}.',
'}}'
}, '\n'))
return report
end
---
-- I18n-js support dashboard.
-- @param {table} frame Frame table from invocation.
-- @return {string} report List of all scripts by I18n-js status
-- @see p.main
function p.imports(frame)
return frame:preprocess(table.concat({
'{{#dpl:',
'| allowcachedresults = 1',
'| ordermethod = title',
'| titleregexp = .+i18n\\.json',
'| namespace = MediaWiki',
'| format = ',
'«table class="WikiaTable sortable" style="margin: 0; width: 100%;"»',
'«tr»',
'«th»Script page:«/th»',
'«th»I18n-js status:«/th»',
'«/tr»,',
'²{#invoke:Project I18n¦importSupport',
'¦MediaWiki:²{#invoke:Project I18n¦importCode',
'¦²{#dpl:',
'¦ allowcachedresults = 1',
'¦ include = {Infobox JavaScript}:Code',
'¦ title = ',
'²{#vardefineecho:PAGENAME¦',
'²{#dplreplace:%PAGE%¦/^.*Custom\\-([^\\/]+).*$/¦\\1}²',
'}²',
'}²',
'¦²{#var:PAGENAME}²',
'}²',
'}²,,',
'«/table»',
'}}',
}))
end
-- .
-- @param {table} frame Frame table from invocation.
-- @param {table} frame.args Arguments table.
-- @param {string} frame.args[1] Package method - report.
-- @param {string} frame.args[2] URL fragment name (for link shortcuts).
-- @param {string} frame.args.langs Boolean for language list.
-- @return {string} report List of all scripts by I18n-js status
-- @see p.main
function p.main(frame)
local method = mw.text.trim(frame.args[1] or '')
local fragment = mw.text.trim(frame.args[2] or '')
local langs = yesno(frame.args.langs, false)
local ret
if langs then
ret = mw.html.create('div')
ret:attr {
['class'] = 'template-documentation',
['id'] = fragment
}
ret:css {
["box-sizing"] = "border-box",
["display"] = "flex",
["flex-flow"] = "column nowrap",
["height"] = "100%",
["margin"] = "0"
}
ret
:wikitext(p.langs(frame))
:newline()
:tag('div')
:attr {
['class'] = 'template-documentation-content'
}
:wikitext(p[method](frame))
:done():newline()
else
ret = p[method](frame)
end
return tostring(ret)
end
-- Utilities for import report (I18n-js).
-- @section import
--- Script name extractor from JSON page name.
function p.importScriptName(frame)
return frame.args[1]:match('Custom%-([^/]+)')
end
--------------------------------------------------------------------------------
-- Gets the code page from a list of links.
--
-- @param {string} scripts
-- @return {string|nil}
--------------------------------------------------------------------------------
local function getScript(scripts)
local modules = {}
for script in scripts:gmatch(':([^:]-%.js)') do
if
script:find('/') == nil or
script:find('/code')
then
table.insert(modules, script)
end
end
return #modules > 0 and modules[#modules] or nil
end
--------------------------------------------------------------------------------
-- Code page extractor from code data.
--
-- @param {Frame} frame
-- @return {string}
--------------------------------------------------------------------------------
function p.importCode(frame)
local scripts = mw.text.trim(frame.args[1] or '')
local default = mw.text.trim(frame.args[2] or '')
local result = getScript(scripts)
if result then
return result
else
local page = default:match(':([^:]-)$') or default;
return getScript(frame:preprocess('{{Code|' .. (default:match(':([^:]-)$') or default) .. '}}'))
or (page:match('(.-)%.js$') or page) .. '.js'
end
end
--- I18n-js status from MediaWiki script page.
function p.importSupport(frame)
local mwPage = mw.text.trim(frame.args[1])
if nonscripts[mwPage] then
return ''
end
local result = frame:preprocess(table.concat({
'{{#dpl:',
'| allowcachedresults = 1',
'| title = ', mwPage,
'| mode = inline',
'| include = *',
'| includematch = /[Ii]18n-js/',
'| includemaxlength = 0',
'| format = ,«!--,--»,',
'| format = ,«!--,--»,',
'| resultsfooter = [[', mwPage, ']]¦1',
'| noresultsfooter = [[', mwPage, ']]¦0',
'}}'
}))
-- Not interested in text that might appear before the footer.
local pageLink, reportBool = string.match(result, "^.*(%[%[.-%]%])|([01])$")
local pageLink = pageLink or ''
local reportBool = yesno(reportBool or '')
local reportField = mw.html.create('tr')
reportField
:tag('td')
:wikitext(pageLink)
:done()
:tag('td')
:tag('small')
:addClass('wds-button')
:css {
['background'] = '#' .. (reportBool and '32cd32' or 'ffba01'),
['border'] = 'none',
['margin'] = '2px',
['padding'] = '0',
['user-select'] = 'none',
['width'] = '1.5em'
}
:wikitext(reportBool and '✓' or '✗')
:done()
:wikitext((reportBool
and ' I18n-js supported'
or ' I18n-js unsupported'
))
:done()
return tostring(reportField)
end
--- Todo list generator in Lua I18n submodules.
function p._todo(source)
local i18n = require('Module:' .. source .. '/i18n')
local content = mw.title.new('Module:' .. source .. '/i18n')
:getContent()
:gsub('\n%-%-[^\n]*', '')
local i18n_languages = {}
local i18n_keys = {}
local maxlen_key = 0
for _, code in ipairs(languages) do
i18n[code] = i18n[code] or {}
end
for key in pairs(i18n.en or {}) do
maxlen_key = #key >= maxlen_key
and #key
or maxlen_key
table.insert(i18n_keys, key)
end
maxlen_key = 1 + math.ceil( (maxlen_key + 2) / 4 ) * 4
table.sort(i18n_keys, function(a, b)
local i1 = content:find('"' .. a .. '"', nil, true)
local i2 = content:find('"' .. b .. '"', nil, true)
return i1 < i2
end)
for code, messages in pairs(i18n) do
if i18n_languages ~= 'en' then
local translated = true
for _, key in pairs(i18n_keys) do
if not i18n[code][key] then
translated = false
break
end
end
if not translated then
table.insert(i18n_languages, code)
end
end
end
table.sort(i18n_languages)
local ret, todo = {}, ''
for _, key in pairs(i18n_keys) do
todo = '-- @todo ' .. padright('"' .. key .. '"', maxlen_key) .. ' -'
for _, code in ipairs(i18n_languages) do
todo = todo .. ' ' .. (not (i18n[code] or {})[key] and code or code:gsub('.', ' '))
end
if not todo:find(' %- +$') then
table.insert(ret, todo)
end
end
return table.concat(ret, '\n')
end
return p