Modul:Vorlage:URN
aus Wikipedia, der freien Enzyklopädie
Vorlagenprogrammierung | Diskussionen | Lua | Unterseiten | |||
Modul | Deutsch | English
|
Modul: | Dokumentation |
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus
local URN = { suite = "URN",
serial = "2020-01-18",
item = 52365013,
globals = { TemplUtl = 52364930,
URIutil = 19644443 }
}
--[=[
Support Template:URN {{URN}}
]=]
local Failsafe = URN
local GlobalMod = URN
local Config = {
self = URN.suite,
errCat = false,
errClass = "error_URN",
errClasses = false,
errHide = false,
errNS = false,
errConflict = { en = "Conflict in multiple parameters",
de = "Konflikt durch überbestimmte Parameter" },
errInvalid = { en = "Invalid:",
de = "Ungültig:" },
errMissing = { en = "Missing ID",
de = "ID fehlt" },
errModule = { en = "Library module missing:",
de = "Bibliotheksmodul fehlt:" },
errUnkown = { en = "Unkown parameter:",
de = "Parameter unbekannt:" }
}
local foreignModule = function ( access, advanced, append, alt, alert )
-- Fetch global module
-- Precondition:
-- access -- string, with name of base module
-- advanced -- true, for require(); else mw.loadData()
-- append -- string, with subpage part, if any; or false
-- alt -- number, of wikidata item of root; or false
-- alert -- true, for throwing error on data problem
-- Postcondition:
-- Returns whatever, probably table
-- 2019-10-29
local storage = access
local finer = function ()
if append then
storage = string.format( "%s/%s",
storage,
append )
end
end
local fun, lucky, r, suited
if advanced then
fun = require
else
fun = mw.loadData
end
GlobalMod.globalModules = GlobalMod.globalModules or { }
suited = GlobalMod.globalModules[ access ]
if not suited then
finer()
lucky, r = pcall( fun, "Module:" .. storage )
end
if not lucky then
if not suited and
type( alt ) == "number" and
alt > 0 then
suited = string.format( "Q%d", alt )
suited = mw.wikibase.getSitelink( suited )
GlobalMod.globalModules[ access ] = suited or true
end
if type( suited ) == "string" then
storage = suited
finer()
lucky, r = pcall( fun, storage )
end
if not lucky and alert then
error( "Missing or invalid page: " .. storage, 0 )
end
end
return r
end -- foreignModule()
local function factory( apply )
-- Localization of messages
-- apply -- string, with message key
-- Returns message text; at least English
local entry = Config[ apply ]
local r
if entry then
-- TODO: page language
r = entry[ mw.language.getContentLanguage():getCode() ]
if not r then
r = entry.en
end
else
r = tostring( mw.html.create( "span" )
:addClass( "error" )
:wikitext( string.format( "????.%s.????",
apply ) ) )
end
return r
end -- factory()
local function faculty( adjust )
-- Test template arg for boolean
-- adjust -- string or nil
-- Returns boolean
local r = false
if adjust then
r = mw.text.trim( adjust )
if r ~= "" and r ~= "0" then
r = true
end
end
return r
end -- faculty()
local function fault( alert, about )
-- Format message with class="error" or similar
-- alert -- string, with message key
-- about -- string, with explanation
-- Returns message with markup
local scope = Config.errClass
local story = factory( alert )
local TemplUtl = foreignModule( "TemplUtl",
true,
false,
URN.globals.TemplUtl )
local r
if type( TemplUtl ) == "table" and
type( TemplUtl.TemplUtl ) == "function" then
TemplUtl = TemplUtl.TemplUtl()
else
TemplUtl = false
end
if Config.self then
story = string.format( "%s * %s", Config.self, story )
end
if about then
story = string.format( "%s %s", story, about )
end
if Config.errClasses then
if scope then
scope = string.format( "%s %s",
scope, Config.errClasses )
else
scope = Config.errClasses
end
end
if TemplUtl then
r = TemplUtl.failure( story,
not Config.errHide,
scope,
Config.frame )
else
r = tostring( mw.html.create( "span" )
:addClass( scope )
:addClass( "error" )
:wikitext( story ) )
end
if Config.errCat then
if Config.errNS then
local ns = mw.title.getCurrentTitle().namespace
local st = type( Config.errNS )
if st == "string" then
local space = string.format( ".*%%s%d%%s.*", ns )
local spaces = string.format( " %s ", Config.errNS )
if spaces:match( space ) then
Config.errNS = false
end
elseif st == "table" then
for i = 1, #Config.errNS do
if Config.errNS[ i ] == ns then
Config.errNS = false
break -- for i
end
end -- for i
end
end
if not Config.errNS then
r = string.format( "%s[[Category:%s]]", r, Config.errCat )
end
end
return r
end -- fault()
local function format( access )
-- Analyze code, create URL
-- access -- table
-- .id -- string, with URN ID component
-- .resolver -- string, or false
-- .fragment -- string, or false
-- Returns string, perhaps with error message
local URIutil = foreignModule( "URIutil",
true,
false,
URN.globals.URIutil )
local r
if type( URIutil ) == "table" and
type( URIutil.URIutil ) == "function" then
URIutil = URIutil.URIutil()
r = URIutil.uriURN( "urn:" .. access.id,
false,
access.resolver,
false,
access.fragment )
if not r:find( "//", 1, true ) then
r = fault( "errInvalid", access.id )
end
else
r = fault( "errModule", "URIutil" )
end
return r
end -- format()
local function main( argsF, argsT )
-- Invocation
-- argsF -- table, with #invoke parameters, or false
-- argsT -- table, with template parameters
-- Returns appropriate string
local r
if argsF then
Config.errCat = argsF.errCat
Config.errClasses = argsF.errClasses
Config.errHide = faculty( argsF.errHide )
Config.errNS = argsF.errNS
end
if type( argsT ) == "table" then
local unknown
r = { }
for k, v in pairs( argsT ) do
s = type( k )
if s == "number" then
if ( k <= 2 ) then
v = mw.text.trim( v )
if v ~= "" then
r[ k ] = v
end
k = false
else
k = tostring( k )
end
elseif s == "string" then
if k == "resolver" or k == "fragment" then
if v ~= "" then
r[ k ] = v
end
k = false
elseif argsF.demo or faculty( argsF.NoCat ) then
Config.errCat = false
Config.errHide = false
k = false
end
end
if k then
if not unknown then
unknown = { }
end
table.insert( unknown, k )
end
end -- for k, v
if unknown then
r = string.format( "'<code>%s</code>' in Template:URN",
table.concat( unknown, " " ) )
r = fault( "errUnkown", r )
elseif r[ 1 ] then
r.id = r[ 1 ]
if r[ 2 ] then
-- transition & migration at dewiki
r.id = string.format( "%s:%s", r.id, r[ 2 ] )
end
r = format( r, r.fragment )
else
r = fault( "errMissing" )
end
end
return r
end -- main()
Failsafe.failsafe = function ( atleast )
-- Retrieve versioning and check for compliance
-- Precondition:
-- atleast -- string, with required version or "wikidata" or "~"
-- or false
-- Postcondition:
-- Returns string -- with queried version, also if problem
-- false -- if appropriate
-- 2019-10-15
local last = ( atleast == "~" )
local since = atleast
local r
if last or since == "wikidata" then
local item = Failsafe.item
since = false
if type( item ) == "number" and item > 0 then
local entity = mw.wikibase.getEntity( string.format( "Q%d",
item ) )
if type( entity ) == "table" then
local seek = Failsafe.serialProperty or "P348"
local vsn = entity:formatPropertyValues( seek )
if type( vsn ) == "table" and
type( vsn.value ) == "string" and
vsn.value ~= "" then
if last and vsn.value == Failsafe.serial then
r = false
else
r = vsn.value
end
end
end
end
end
if type( r ) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial
else
r = false
end
end
return r
end -- Failsafe.failsafe()
-- Export
local p = { }
p.f = function ( frame )
local lucky, r
Config.frame = frame
lucky, r = pcall( main, frame.args, frame:getParent().args )
if not lucky then
r = tostring( mw.html.create( "span" )
:addClass( "error" )
:wikitext( string.format( "%s * %s",
frame:getTitle(),
r ) ) )
end
return r
end -- p.f()
p.failsafe = function ( frame )
-- Versioning interface
local s = type( frame )
local since
if s == "table" then
since = frame.args[ 1 ]
elseif s == "string" then
since = frame
end
if since then
since = mw.text.trim( since )
if since == "" then
since = false
end
end
return Failsafe.failsafe( since ) or ""
end -- p.failsafe()
p.test = function ( argsF, argsT )
lucky, r = pcall( main, argsF, argsT )
return r
end -- p.test()
return p