細
small tweak related to unsupported rtl languages
細 (1版 をインポートしました) |
bsd>Jarekt 細 (small tweak related to unsupported rtl languages) |
||
6行目: | 6行目: | ||
|_| |_|\___/ \__,_|\__,_|_|\___(_)\____\___/|_| \___| | |_| |_|\___/ \__,_|\__,_|_|\___(_)\____\___/|_| \___| | ||
Core is a meta-module that consists of common and useful Lua functions that can | |||
creating infobox templates on Commons. | be used in many Lua scripts. It was writen as a core of several Lua | ||
modules for creating file infobox templates on Commons. Many of the functions | |||
are bare-bones versions of full functions found in other modules. | |||
Authors and maintainers: | Authors and maintainers: | ||
16行目: | 18行目: | ||
------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ||
-- Based on frame structure create "args" table with all the input parameters | --[[ | ||
- | Based on frame structure create "args" table with all the input parameters: | ||
* table keys - equivalent to template parameters are converted to lower case | |||
so they will not be case-sensitive. | |||
Also underscored are treated the same way as speces. | |||
* table values - input values are trimmed (whitespaces removed from the beggining | |||
and the end) and empty string are converted to nils. | |||
If "lang" is not provided than we substitute user's prefered language. | |||
This function collects inputs from both frame and frame's parent. See | |||
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame:getParent . | |||
If both structures have the same field than value from "frame" takes priority. | |||
Inputs: | |||
1) frame - frame objects see below for details | |||
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#frame-object | |||
See also: Module:Arguments on enWiki - which is much larger single purpose module | |||
]] | |||
function core.getArgs(frame) | function core.getArgs(frame) | ||
local function normalize_input_args(input_args, output_args) | local function normalize_input_args(input_args, output_args) | ||
for name, value in pairs( input_args ) do | for name, value in pairs( input_args ) do | ||
value = | value = mw.text.trim(value) -- trim whitespaces from the beggining and the end of the string | ||
if value ~= '' then -- nuke empty strings | if value ~= '' then -- nuke empty strings | ||
if type(name)=='string' then | if type(name)=='string' then | ||
45行目: | 62行目: | ||
------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ||
-- code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch | --[[ | ||
function core. | Simplified code equivalent to https://commons.wikimedia.org/wiki/Template:LangSwitch | ||
Example usage: | |||
text = langSwitch({en='text in english', pl='tekst po polsku'}, lang) | |||
Inputs: | |||
1: args - table with translations by language | |||
2: lang - desired language (often user's native language) | |||
Outputs: | |||
1: label - returned label | |||
2: lang - language of the label (langSwitchWithLang only) | |||
]] | |||
function core.langSwitchWithLang(args, lang) | |||
local langList = mw.language.getFallbacksFor(lang) | local langList = mw.language.getFallbacksFor(lang) | ||
table.insert(langList,1,lang) | table.insert(langList,1,lang) | ||
for i,language in ipairs(langList) do | for i,language in ipairs(langList) do | ||
if | if args[language] then | ||
return | return args[language], language | ||
end | end | ||
end | end | ||
end | |||
function core.langSwitch(args, lang) | |||
local label, lang = core.langSwitchWithLang(args, lang) | |||
return label | |||
end | end | ||
------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ||
-- Function allowing for consistent treatment of boolean-like wikitext input. | --[[ | ||
-- It works similarly to Module:Yesno | display a language followed by a message. Like "English: Hello" with extensive HTML marking | ||
Code equivalent to https://commons.wikimedia.org/wiki/Template:Description | |||
Inputs: | |||
1) text_lang - language code for the above text, also used as a name of the CSS formating class | |||
2) text - description text to display | |||
3) args - additional optional arguments. Numbers in perenthesis are parameter numbers in the original template. | |||
* hover - (3) hover aka mouseover aka tooltip text | |||
* lang_tag - (4) standard code for lang tag in HTML (optional, default is same as text_lang) | |||
* ext - (5) extension text shown after the language name before colon (optional, default is empty) | |||
* inline - Optional, default is false. When set to true, forces the template to be displayed | |||
inline, so that it does not break the current paragraph (that makes possible to put several | |||
descriptions side by side on a single line) | |||
]] | |||
function core.langWrapper(text_lang, text, args) | |||
local dir, space, colon, lang_name, hover | |||
local inline = core.yesno(args.inline, false) and 'inline' or nil | |||
if mw.language.isKnownLanguageTag(text_lang) then -- supported language | |||
local langObj = mw.language.new( text_lang ) | |||
dir = langObj:getDir() -- text direction | |||
space = mw.message.new( "Word-separator" ):inLanguage(text_lang):plain() | |||
colon = mw.message.new( "Colon" ):inLanguage(text_lang):plain() | |||
hover = mw.language.fetchLanguageName( text_lang, args.user_lang or 'en') | |||
lang_name = mw.language.fetchLanguageName( text_lang, text_lang) | |||
lang_name = langObj:ucfirst(lang_name) | |||
else -- unsuported language | |||
local RTL_LUT = {['fa-af']=1, prd=1, ydd=1} | |||
dir = (RTL_LUT[text_lang]==1 or text_lang:gsub('-arab', '')~=text_lang) and 'rtl' or 'ltr' | |||
space = ' ' | |||
colon = ':' | |||
hover = args.hover | |||
lang_name = text_lang or 'Unknown' | |||
end | |||
lang_name = args.lang_name or lang_name-- user provided args.lang_name takes presedent | |||
lang_name = '<b>' .. lang_name .. (args.ext or '') .. colon .. '</b>' | |||
-- create HTML | |||
local ltag = mw.html.create('span') -- bold language name string | |||
:addClass('language') -- class: "language" | |||
:addClass(text_lang) -- class: "en", "de" etc. | |||
:attr('title', hover) -- add hover aka mouseover aka tooltip text | |||
:wikitext(lang_name) | |||
local dtag = mw.html.create('div') | |||
:addClass('description') -- div.description is tracked by mw:Extension:CommonsMetadata | |||
:addClass('mw-content-'..dir) -- mw-content-rtl and mw-content-ltr are defined in mediawiki-code (https://gerrit.wikimedia.org/r/c/mediawiki/core/+/208332) | |||
:addClass(text_lang) -- not sure where "en", "de" etc. are defined | |||
:attr('dir', dir) | |||
:attr('lang', text_lang) | |||
:css('display', inline) | |||
:wikitext(tostring(ltag) .. space .. text) | |||
return tostring(dtag) | |||
end | |||
------------------------------------------------------------------------------ | |||
--[[ | |||
Function allowing for consistent treatment of boolean-like wikitext input. | |||
Inputs: | |||
1) val - value to be evaluated, outputs as a function of values: | |||
true : true (boolean), 1 (number), or strings: "yes", "y", "true", "1" | |||
false : false (boolean), 0 (number), or strings: "no", "n", "false", "0" | |||
2) default - value to return otherwise | |||
See Also: It works similarly to Module:Yesno | |||
]] | |||
function core.yesno(val, default) | function core.yesno(val, default) | ||
if type(val) == 'boolean' then | if type(val) == 'boolean' then | ||
return val | return val | ||
elseif type(val) == 'number' then | elseif type(val) == 'number' then | ||
if val== | val = tostring(val) | ||
end | |||
if type(val) == 'string' then | |||
return | local LUT = { | ||
yes=true , y=true , ['true'] =true , t=true , ['1']=true , on =true, | |||
no =false, n=false, ['false']=false, f=false, ['0']=false, off=false } | |||
val = LUT[mw.ustring.lower(val)] -- put in lower case | |||
if (val~=nil) then | |||
return val | |||
end | end | ||
end | end | ||
return default | return default | ||
80行目: | 174行目: | ||
------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ||
-- | --[[ | ||
Read Commons Data:SOMENAME.tab dataset and look for message identified by a | |||
"key" in a language "lang". See editAtWikidata for an example. It uses | |||
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.ext.data | |||
Inputs: | |||
1) dataset - name of commons page in "data" namespace. for example "I18n/EditAt.tab" | |||
for c:Data:I18n/EditAt.tab | |||
2) key - which message to pull | |||
3) lang - desired language of the message | |||
Output: message as a string | |||
]] | |||
function core.formatMessage(dataset, key, lang) | function core.formatMessage(dataset, key, lang) | ||
for _, row in pairs(mw.ext.data.get(dataset, lang).data) do | for _, row in pairs(mw.ext.data.get(dataset, lang).data) do | ||
92行目: | 196行目: | ||
end | end | ||
------------------------------------------------------------------------------ | |||
-- Assembles the "Edit at Wikidata" pen icon and returns it as wikitext string. | --[[ | ||
-- Dependencies: Data:I18n/EditAt.tab | Assembles the "Edit at Wikidata" pen icon with a link to Wikidata page or specific | ||
property and returns it as wikitext string. | |||
Inputs: | |||
1) entityID - wikidata entity object for a given page (output of wikibase.getEntity( id )) | |||
2) propertyID - string like 'P31' so the link will point to that specific property. Use "" | |||
to link to the whole page. | |||
3) lang - language of the "Edit at Wikidata" message | |||
Dependencies: Data:I18n/EditAt.tab | |||
See Also: en:Module:EditAtWikidata | |||
]] | |||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
function core.editAtWikidata(entityID, propertyID, lang) | function core.editAtWikidata(entityID, propertyID, lang) | ||
102行目: | 215行目: | ||
end | end | ||
------------------------------------------------------------------------------ | |||
-- Assembles the "Edit at SDC" pen icon and returns it as wikitext string. | --[[ | ||
-- Dependencies: Data:I18n/EditAt.tab | Assembles the "Edit at SDC" pen icon with a link to a property in SDC part of the current file | ||
page, and returns it as wikitext string. | |||
Inputs: | |||
2) propertyID - string like 'P31' so the link will point to that specific property. Use 'ooui-php-4' | |||
to link to the label section. | |||
3) lang - language of the "Edit at Wikidata" message | |||
Dependencies: Data:I18n/EditAt.tab | |||
See Also: en:Module:EditAtWikidata | |||
]] | |||
function core.editAtSDC(propertyID, lang) | function core.editAtSDC(propertyID, lang) | ||
local msg = core.formatMessage('I18n/EditAt.tab', 'EditAtSDC', lang) | local msg = core.formatMessage('I18n/EditAt.tab', 'EditAtSDC', lang) | ||
113行目: | 233行目: | ||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||
function | --[[ | ||
This function returns a label translated to desired language, created based on wikidata | |||
Code equivalent to require("Module:Wikidata label")._getLabel | |||
Inputs: | |||
1: item - wikidata's item's q-id or entity class | |||
2: userLang - desired language of the label | |||
]] | |||
function core.getLabel(item, userLang) | |||
local label, link | local label, link | ||
-- build language fallback list | -- build language fallback list | ||
local langList = mw.language.getFallbacksFor(userLang) | local langList = mw.language.getFallbacksFor(userLang) | ||
table.insert(langList, 1, userLang) | table.insert(langList, 1, userLang) | ||
-- get label | |||
for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | ||
label = mw.wikibase.getLabelByLang( | label = mw.wikibase.getLabelByLang(item, lang) | ||
if label then break end -- label found and we are done | if label then break end -- label found and we are done | ||
end | end | ||
label = label or item -- fallback value | |||
-- get link | |||
for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | for _, lang in ipairs(langList) do -- loop over language fallback list looking for label in the specific language | ||
link = mw.wikibase.getSitelink( | link = mw.wikibase.getSitelink(item, lang .. 'wiki') | ||
if link then | if link then | ||
link = mw.ustring.format('w:%s:%s', lang, link) | link = mw.ustring.format('w:%s:%s', lang, link) | ||
break | break | ||
end | end | ||
end | end | ||
link | link = link or 'd:'..item -- fallback value | ||
label = label | -- look for description | ||
local desc = mw.wikibase.getDescription(item) | |||
if desc then -- add description if we have one | |||
desc = mw.text.nowiki(desc) -- add description as hover text | |||
label = '<span title="' .. desc .. '">' .. label .. '</span>' | |||
end | |||
return '[['..link..'|'..label..']]' | |||
end | |||
------------------------------------------------------------------------------- | |||
--[[ | |||
Core component of many "get property value" functions | |||
Example: (core.parse_statements(entity:getBestStatements( prop ), nil) or {nil})[1] would | |||
return the first best statement | |||
Inputs: | |||
1: statements - can be provided by: | |||
* entity:getBestStatements( prop ) | |||
* entity:getAllStatements( prop ) | |||
* mw.wikibase.getBestStatements( item, prop ) | |||
* mw.wikibase.getAllStatements( item, prop ) | |||
2: lang - language code (like "en"), if provided than item IDs will be | |||
changed to a label | |||
Output: | |||
* table of strings or nil | |||
]] | |||
function core.parseStatements(statements, lang) | |||
local output = {} | |||
for _, statement in ipairs(statements) do | |||
if (statement.mainsnak.snaktype == "value") and (statement.rank ~= 'deprecated') then | |||
local val = statement.mainsnak.datavalue.value | |||
if val.id then | |||
val = val.id | |||
if lang ~= nil then | |||
val = core.getLabel(val, lang) | |||
end | |||
elseif val.text then | |||
val = val.text | |||
elseif val.amount then | |||
val = tonumber(val.amount) | |||
end | |||
table.insert(output, val) | |||
end | |||
end | |||
if #output==0 then return nil end | |||
return output | |||
end | end | ||
return core | return core |