Module:Title
Jump to navigation
Jump to search
Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules
This module is intended to be the engine behind {{Title}}
Code
--[[
__ __ _ _ _____ _ _ _
| \/ | ___ __| |_ _| | ___ |_ _(_) |_| | ___
| |\/| |/ _ \ / _` | | | | |/ _ (_)| | | | __| |/ _ \
| | | | (_) | (_| | |_| | | __/_ | | | | |_| | __/
|_| |_|\___/ \__,_|\__,_|_|\___(_)|_| |_|\__|_|\___|
This module is intended to be the engine behind "Template:Title"
Authors and maintainers:
* User:Jarekt - original version
]]
require('strict') -- used for debugging purposes as it detects cases of unintended global variables
local core = require('Module:Core')
local createTag = require('Module:TagQS').createTag
-- ==================================================
-- === Internal functions ===========================
-- ==================================================
------------------------------------------------------------------------------
-- Clone of core.getArgs except for adding args.lang
-- Based on frame structure create "args" table with all the input parameters.
-- All inputs are not not case-sensitive and underscored are treated the same
-- way as speces. Input values are trimmed and empty string are converted to
-- nils.
local function getArgs(frame)
local function normalize_input_args(input_args, output_args)
for name, value in pairs( input_args ) do
if type(name)=='string' and value ~= '' then
output_args[string.lower(name)] = value
end
end
return output_args
end
local args = {}
args = normalize_input_args(frame:getParent().args, args)
args = normalize_input_args(frame.args, args)
return args
end
-- ====================================================================
local function style(str, textLang)
-- based on [[Template:Title/style]]
if not str or #str==0 then
return nil
end
str = mw.text.trim(str)
local LUT = {ar='%s',he='%s' ,et='„%s“' ,ja='『%s』' ,mk='„%s“' ,ru='«%s»' ,zh='《%s》', ['zh-hans']='《%s》', en='<i>%s</i>'}
--str = mw.language:ucfirst(str)
local form = core.langSwitchWithLang(LUT, textLang)
str = mw.ustring.format( form, str) -- place quotes
local dir = mw.language.new( textLang ):getDir()
str = string.format('<div style="display:inline-block" dir="%s" lang="%s">%s</div>', dir, textLang, str)
return str
end
-- ===========================================================================
-- === get wikidata item ID (qid) based on P6243 stored in SDC ===
-- ===========================================================================
local function qid_from_SDC()
local page = mw.title.getCurrentTitle()
if page.namespace==6 then -- File namespace
local entity = mw.wikibase.getEntity()
if entity and entity.statements and entity.statements.P6243 then
local statement = entity.statements.P6243[1]
return statement.mainsnak.datavalue.value.id
end
end
return nil
end
-- ====================================================================
local function harvest_wikidata(entity, userLang)
local data = {} -- structure similar to "args" but filled with wikidata data
data.userLang = userLang
if not entity then
return data
end
-- get title (from 3 properties and label)
local property = {P1476 = 'title', P1448='official_name', P1705='native_label'}
for prop, field in pairs( property ) do
local titleList = {}
for _, statement in pairs( entity:getBestStatements(field)) do
if (statement.mainsnak.snaktype == "value") then
local val = statement.mainsnak.datavalue.value
titleList[val.language] = val.text -- look for multiple values each with a language code
data.title, data.lang = val.text, val.language -- in case we have title in some odd language: capture it
end
end
if #titleList>1 then
local title, language = core.langSwitch(titleList, userLang)
if title then
data.title, data.lang = title, language
end
end
if data.title then
data.title = data.title .. core.editAtWikidata(entity.id, prop, userLang)
break -- title found so no need for other property
end
end
-- get labels in all the langguages
if entity.labels then
for _, val in pairs(entity.labels) do -- loop over all labels
if val.language~=data.lang then
data[val.language] = val.value
end
end
end
return data
end
local function quote(str)
return '"' .. str .. '"'
end
-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}
-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p.title_(args)
local line1, line2, Title, text, lang
local colon = mw.message.new( "colon" ):inLanguage(args.userLang ):plain()
local wordsep = mw.message.new( "Word-separator" ):inLanguage(args.userLang ):plain()
local qsTable = {}
if args.lang and args.title then -- == Case 1: original language to be displayed ==
args.lang = string.lower(args.lang)
line1 = style(args.title, args.lang) -- first line
if args.lang==args.userLang then -- user's language = title's language
Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', line1 or '')
else -- user's language != title's language
-- line 1 original language
local langName = mw.language.fetchLanguageName( args.lang, args.userLang )
line1 = langName .. colon .. wordsep .. line1 -- add language name to line #1
if args.transliteration then
line1 = line1 .. ' - ' .. args.transliteration
end
line1 = mw.ustring.format( '<div style="font-size:0.9em;display:inline-block;">%s</div>', line1)
-- line 2 translation
if args.translation then
line2 = args.translation
else
text, lang = core.langSwitchWithLang(args, args.userLang)
line2 = style(text, lang)
end
if line2 then
line2 = mw.ustring.format( '<br/><div style="font-weight:bold;display:inline-block;">%s</div>', line2)
end
Title = line1 .. (line2 or '')
end
if not args.title_ then -- make sure title did not originated on wikidata
table.insert( qsTable, createTag('title', 'P1476', args.lang .. ':' .. quote(args.title)) )
table.insert( qsTable, createTag('label', 'L'..args.lang, quote(args.title)) )
end
else -- == Case 2: original language not relevant ==
if args.title then
Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', args.title )
else
text, lang = core.langSwitchWithLang(args, args.userLang)
if text then
Title = style(text, lang)
Title = mw.ustring.format( '<div style="font-weight:bold;display:inline-block;">%s</div>', Title)
else -- list them all
local Titles = {}
for lang, text in pairs(args) do
if type(lang)=='string' and mw.language.isSupportedLanguage( lang ) then
local langName = mw.language.fetchLanguageName( lang, args.userLang )
table.insert(Titles, langName .. colon .. wordsep .. style(text, lang) )
end
end
Title = table.concat(Titles, '\n')
end
end
end
Title = Title or ''
if args.comment then
Title = mw.ustring.format( '%s<br /><div style="font-size:0.9em;display:inline-block;">%s<br /></div>', title, args.comment)
end
-- add text of invisible tag brodcasted by the template which allows creation of QuickStatements command used to add this info to Wikidata
for lang, text in pairs( args ) do
if type(lang)=='string' and mw.language.isSupportedLanguage(lang) and not args[lang..'_'] then -- lang has tobe a valid language and the statement is not from wikidata
table.insert( qsTable, createTag('label', 'L'..lang, quote(text)) )
end
end
return Title .. table.concat( qsTable, '\n')
end
function p.wikidata_title(entity, userLang)
return p.title_(harvest_wikidata(entity, userLang))
end
-- ===========================================================================
-- === Versions of the function to be called from template namespace
-- ===========================================================================
function p.title(frame)
-- args.lang is usually provided and it is used for the language of the title
-- not customary language of the user which can be provided by args.userlang
local args = getArgs(frame)
args.userLang = args.userlang
if not (args.userLang and mw.language.isSupportedLanguage(args.userLang)) then
args.userLang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
end
-- merge wikidata with local variables
local qid = args.wikidata or qid_from_SDC() -- get wikidata item ID based on P6243 stored in SDC
if qid then
local entity = mw.wikibase.getEntity(qid)
if entity then
local data = harvest_wikidata(entity, args.userLang)
if not args.title and data.title and not args.lang and data.lang then
args.title = data.title -- get title from wikidata
args.lang = data.lang
args.title_ = 'from wikidata'
end
for lang, text in pairs( data ) do
if mw.language.isSupportedLanguage(lang) and not args[lang] then
args[lang] = text
args[lang..'_'] = 'from wikidata'
end
end
end
end
return p.title_(args)
end
return p