Modul:GlobalSharing
| Vorlagenprogrammierung | Diskussionen | Lua | Unterseiten | |||
| Modul | Deutsch | English
|
Modul: | Dokumentation | ||
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus
Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData:
2026-06-01local GlobalSharing = { suite = "GlobalSharing",
serial = "2026-06-01",
item = 76292536,
globals = { Multilingual = 47541920,
WikidataScheme = 74420405 } }
--[=[
Support for sharing things in the WMF world
]=]
local Failsafe = GlobalSharing
local GlobalMod = GlobalSharing
local Config = { ltr = true }
local Data = { }
local Present = { }
local Text
Config.profiles = { [-12] = { -- Bot
source = { nil, "()url" },
doc = { "()url" },
},
[-11] = { -- labsBot
source = { nil, "()url" },
doc = { "()url" }
},
[-10] = { -- labsTool
source = { nil, "()url" },
doc = { "()url" },
start = { "()url Toolforge" }
},
[4] = { -- Project page
source = { nil },
linkSite = true
},
[10] = { -- template
type = { "template" },
source = { "()url WMF 10" },
doc = { "()url WMF" },
},
[828] = { -- module
type = { "module" },
proglang = { "lua" },
source = { "()url WMF 828" },
doc = { "()url WMF" },
},
[2300] = { -- skin resource
type = { "gadget" },
proglang = { "javascript",
"json",
"css" },
source = { "()url WMF 2,8,2300" },
doc = { "()url WMF" }
}
}
Config.spaces = { L = "Lexeme:",
P = "Property:",
Q = false }
Config.pages = { User = 2300,
Template = 10,
Mediawiki = 2300,
Module = 828,
Gadgets = 2300 }
Config.sites = { mediawiki = true,
wikibooks = true,
wikidata = true,
wikimedia = true,
wikinews = true,
wikipedia = true,
wikiquote = true,
wikisource = true,
wikiversity = true,
wikivoyage = true,
wiktionary = true }
Config.icons =
{ npx = 28,
download = { source = "Codex icon download color-progressive.svg",
support = "Update" },
home = { source = "Noun 1580514 3333ff.svg",
support = "Upstream" },
wikidata = { source = "Wikidata-logo.svg",
support = "Wikidata Logo" }
}
Config.css = { ["="] = { ["background-color"] = "#00FF00",
color = "#000000" },
[">"] = { ["background-color"] = "#FF0000",
color = "#FFFF00" },
["?"] = { ["background-color"] = "#FFFF00",
color = "#000000" },
["#"] = { display = "inline-block",
["font-size"] = "120%",
["font-weight"] = "900",
["margin-left"] = "1em",
["margin-right"] = "1em",
["padding-left"] = "1em",
["padding-right"] = "1em"
}
}
Config.errors = { bag = false }
Data.resolve = { source = { P = 1324 },
host = { P = 137 },
version = { P = 348 },
licence = { P = 275 },
usedby = { P = 1535 },
uses = { P = 2283 },
doc = { P = 973 },
doclang = { P = 407 },
iso6391 = { P = 218 },
iso6392 = { P = 219 },
tags = { P = 366 },
linksite = { Q = 677652 },
upgrade = { Q = 920419 },
upstream = { Q = 352213 },
wikidata = { Q = 2013 }
}
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 failures = function ()
-- Summarize all faults
-- Postcondition:
-- Returns string, hopefully empty
local r
if Config.errors.bag then
local max = 1000000000
local id = math.floor( os.clock() * max )
local show = string.format( "%s * Errors",
WikidataScheme.suite )
local sign = string.format( "error_%d", id )
local errors = mw.html.create( "ul" )
:addClass( "error" )
local e = mw.html.create( "h2" )
:addClass( "error" )
:attr( "id", sign )
:wikitext( show )
for i = 1, #Config.errors.bag do
errors:newline()
:node( mw.html.create( "li" )
:addClass( "error" )
:wikitext( Config.errors.bag[ i ] ) )
end -- for i
r = string.format( "%s\n%s\n",
tostring( e ), tostring( errors ) )
show = string.format( "[[#%s|%s]]", sign, WikidataScheme.suite )
mw.addWarning( show )
end
Config.errors.bag = false
return r or ""
end -- failures()
local fault = function ( alert )
-- Format one error message in HTML
-- Precondition:
-- alert -- string, plain error message
-- Postcondition:
-- Returns string, HTML error message
local e = mw.html.create( "span" )
:addClass( "error" )
:wikitext( alert )
Config.errors.bag = Config.errors.bag or { }
table.insert( Config.errors.bag, alert or "??fault??" )
return tostring( e )
end -- fault()
local first = function ( atleast, actual )
-- Check whether local version is matched
-- Precondition:
-- atleast -- string, with global version, or not
-- actual -- string, with local version, or not
-- Postcondition:
-- Returns
-- "=", if equal
-- ">", if update recommended
-- "<", if local newer than global (may be upstream)
-- "?", if strange data
-- else unknown
local r
if type( atleast ) == "string" and
type( actual ) == "string" then
local sg = mw.text.trim( atleast )
local sl = mw.text.trim( actual )
if sg == sl then
r = "="
elseif sg == "" or sl == "" then
r = "?"
elseif sg:match( "^[0-9.]+$" ) and
sl:match( "^[0-9.]+$" ) then
local f = function ( a )
if not a or a == "" then
return -1
end
return tonumber( a )
end
local vg = mw.text.split( sg, "%.+" )
local vl = mw.text.split( sl, "%.+" )
local kg, kl
r = "?"
for i = 1, #vg do
kg = f( vg[ i ] )
kl = f( vl[ i ] )
if kg < 0 or kl < 0 then
break -- for i
elseif kg > kl then
r = ">"
break -- for i
else
r = "="
end
end -- for i
if r == "=" and #vl > #vg then
r = "?"
end
elseif sg > sl then
r = ">"
else
r = "<"
end
end
return r
end -- first()
local found = function ( at, area )
-- Check whether local source code (copy) is present
-- Precondition:
-- at -- string, with local page name
-- area -- number, of required namespace
-- Postcondition:
-- Returns
-- title object, if appropriate
-- string, if bad page name
-- nil, if not found
local t = mw.title.new( at )
local r
if t and t.exists then
if t.namespace == area or
( area == 10 and t.namespace == 4 ) then
r = t
else
r = at
end
end
return r
end -- found()
Config.fetch = function ( access, at )
-- Retrieve external module
-- Precondition:
-- access -- string, with requested name
-- at -- table, for hosting
if not at[ access ] and at[ access ] ~= false then
local bib = foreignModule( access,
true,
false,
GlobalSharing.globals[ access ],
true )
if type( bib ) == "table" and
type( bib[ access ] ) == "function" then
at[ access ] = bib[ access ]()
else
at[ access ] = false
end
end
end -- Config.fetch()
Config.first = function ()
-- Initialize generally
Config.fetch( "Multilingual", Present )
Config.fetch( "WikidataScheme", GlobalSharing )
if GlobalSharing.WikidataScheme then
Text = GlobalSharing.WikidataScheme.Text
Text.flipper( GlobalSharing.suite )
end
end -- Config.first()
Config.from = function ()
-- Initialize current site
-- Postcondition:
-- Returns string, with normalized site
if not Config.server then
local i
Config.server = mw.site.server
if Config.server:sub( 1, 2 ) == "//" then
Config.server = "https:" .. Config.server
end
i = Config.server:find( "[/.]m%." )
if i and i < 20 then
Config.server = Config.server:sub( 1, i + 1 ) ..
Config.server:sub( i + 4 )
end
if Config.server:sub( -1, 1 ) == "/" then
Config.server = Config.server:sub( 1, #Config.server - 1 )
end
end
return Config.server
end -- Config.from()
Data.father = function ( all )
-- Check whether source matches upstream condition
-- Precondition:
-- all -- item object
-- Postcondition:
-- Returns mw.html object, or not
local source = Data.find( all, "source", 1 )
local r
if source then
local start = Config.from() .. "/wiki/"
if source:find( start ) == 1 then
local i
start = source:sub( #start + 1 )
i = start:find( ":" )
if i > 2 then
local space = start:sub( 1, i - 1 )
if ( Config.pages[ space ] ) then
local t = mw.title.makeTitle( space,
start:sub( i + 1 ) )
if not Config.title then
Config.title = mw.title.getCurrentTitle()
end
r = mw.title.equals( Config.title, t )
end
end
end
end
return r
end -- Data.father()
Data.fetch = function ( access )
-- Resolve entity name
-- Precondition:
-- access -- string, with entity name or ID
-- Postcondition:
-- Returns string or not, with entity ID
local r
if access:find( "^[PQL]%d+$" ) then
r = access
elseif type( Data.resolve[ access ] ) == "table" then
local entry = Data.resolve[ access ]
if type( entry ) == "table" then
for k, v in pairs( Config.spaces ) do
if type( entry[ k ] ) == "number" then
r = string.format( "%s%d", k, entry[ k ] )
break -- for k, v
end
end -- for k, v
end
end
return r
end -- Data.fetch()
Data.final = function ( all )
-- Retrieve upstream source code URL
-- Precondition:
-- all -- item object
-- Postcondition:
-- Returns string, or not
local t = Data.full( 0 )
local r
if t then
r = all.id:match( "^Q(%d+)$" )
r = t[ tonumber( r ) ]
if type( r ) ~= "string" or
r:sub( 1, 8 ) ~= "https://" then
r = false
else
local seek = "^https://[a-z_.]+%.(%l+)%.org/wiki/(%u%l+):"
local site, space = r:match( seek )
if Config.sites[ site ] then
space = Config.pages[ space ]
if space ~= 10 and space ~= 828 then
r = false
end
else
r = false
end
end
end
return r
end -- Data.final()
Data.find = function ( all, assign, at )
-- Retrieve entity value
-- Precondition:
-- all -- item object
-- assign -- string, with entity name
-- at -- number, with value counter, or not
-- Postcondition:
-- Returns
-- 1. value, or not
-- 2. qualifiers, if any
local r1, r2
if type( assign ) == "string" then
local k = at or 1
local s = Data.fetch( assign )
local d = all.claims
if s and
type( d ) == "table" and
type( d[ s ] ) == "table" and
type( d[ s ][ k ] ) == "table" then
d = d[ s ][ k ]
if type( d.mainsnak ) == "table" and
type( d.mainsnak.datavalue ) == "table" then
r1 = d.mainsnak.datavalue.value
if type( d.qualifiers ) == "table" then
r2 = d.qualifiers
end
end
end
end
return r1, r2
end -- Data.find()
Data.full = function ( area )
-- Retrieve one Data.tab element
-- Precondition:
-- area -- number, of collection; 0 for URL, 10, 828, 2300
-- Returns: table, or not
-- 0 -- map, item -> URL
-- else -- sequence of Q
local r
Data.collections = Data.collections or { }
r = Data.collections[ area ]
if type( r ) == "nil" and type( area ) == "number" then
local storage = string.format( "%s/%d.tab",
GlobalSharing.suite, area )
local lucky, data = pcall( mw.ext.data.get, storage )
r = false
if type( data ) == "table" and
type( data.data ) == "table" then
data = data.data
if #data > 0 then
local low = ( area ~= 0 )
local dup = { }
local entry, k
r = { }
for i = 1, #data do
entry = data[ i ]
if type( entry ) == "table" then
k = entry[ 1 ]
if low then
if not dup[ k ] then
table.insert( r, k )
dup[ k ] = true
end
else
r[ k ] = entry[ 2 ]
end
end
end -- for i
if type( k ) ~= "number" or
( low and type( entry[ 2 ] ) ~= "string" ) then
r = false
end
end
end
Data.collections[ area ] = r
end
return r
end -- Data.full()
Present.facet = function ( access )
-- Create decorated Wikidata link
-- Precondition:
-- access -- string, with item ID
-- Postcondition:
-- Returns mw.html object
local r = mw.html.create( "span" )
local s = string.format( "[[d:%s|%s]]", access, access )
r:node( Present.flag( "wikidata" ) )
:newline()
:node( mw.html.create( "code" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( s ) )
return r
end -- Present.facet()
Present.failsafe = function ( about, atleast )
-- Check local version
-- Precondition:
-- about -- mw.title object
-- atleast -- string, with global version
-- Postcondition:
-- Returns mw.html object, or not
local r
if about.namespace == 828 and type( atleast ) == "string" then
local lucky, x = pcall( require, about.prefixedText )
if type( x ) == "table" and x.failsafe then
local s = type( x.failsafe )
if s == "function" then
s = x.failsafe()
elseif s == "string" then
s = x.failsafe
else
s = false
end
if s then
r = first( atleast, s )
if r then
local e, css
if r == ">" or r == "<" then
s = mw.text.nowiki( tostring( s ) )
e = mw.html.create( "code" )
:wikitext( s )
if r == "<" then
r = "?"
end
end
css = Config.css[ r ]
r = mw.html.create( "span" )
:css( Config.css[ "#" ] )
:wikitext( mw.text.nowiki( r ) )
if css then
r:css( css )
end
if e then
r = mw.html.create( "span" )
:node( r )
:node( e )
end
end
end
end
end
return r
end -- Present.failsafe()
Present.father = function ()
-- Create decorated upstream indicator
-- Postcondition:
-- Returns mw.html object
if not Present.upstream then
local e = mw.html.create( "span" )
:attr( { dir = "ltr",
lang = "en",
title = "Upstream" } )
:css( { ["background-color"] = "#B0FFB0" } )
local s = "Upstream"
if Data.resolve.upstream and
Data.resolve.upstream.Q then
local sq = string.format( "Q%d", Data.resolve.upstream.Q )
local sl = mw.wikibase.getSitelink( sq )
if not sl then
sl = mw.wikibase.getSitelink( sq, "enwiki" )
if sl then
sl = "w:en:" .. sl
end
end
if sl then
s = string.format( "[[%s|%s]]", sl, s )
end
end
e:wikitext( s )
Present.upstream = mw.html.create( "span" )
:node( Present.flag( "home" ) )
:newline()
:node( e )
end
return Present.upstream
end -- Present.father()
Present.features = function ( access, adjust )
-- Description term etc. of one item
-- Precondition:
-- access -- number, of item
-- adjust -- table, with options
-- .locally -- local sources only
-- .namespace -- number, of repo resource
-- .wikidata -- show link to item
-- .linksite -- show link to page
-- .source -- show link to local source
-- .host -- show link to global source host
-- Postcondition:
-- Returns
-- 1. table, with sequence of mw.html objects DT, DD, DD, DD
-- or not, if unavailable local source queried
-- 2. string, with sort key
local s = string.format( "Q%d", access )
local e, q, r1, r2, slang, source
if mw.wikibase.isValidEntityId( s ) and
mw.wikibase.entityExists( s ) then
q = mw.wikibase.getEntity( s )
end
if q and adjust.locally then
source = Present.fresh( q, adjust.namespace )
if not source then
q = false
end
end
s = type( q )
if s == "table" then
s, slang = Present.wikibase( q, false )
if s then
r2 = s:lower()
if adjust.linksite then
if q.sitelinks then
Config.site = Config.site or
mw.wikibase.getGlobalSiteId()
e = q.sitelinks[ Config.site ]
if e and e.title then
s = string.format( "[[%s|%s]]", e.title, s )
end
end
else
s = Present.find( q, s )
end
e = Text.html( s, "dt", false, slang )
else
e = mw.html.create( "dt" )
:node( mw.html.create( "code" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( string.format( "Q%d",
access )
) )
end
elseif s == "nil" then
e = mw.html.create( "dt" )
:wikitext( fault( Text.flip( "err_ItemUnknown" ) ) )
:node( mw.html.create( "code" )
:attr( "dir", "ltr" )
:attr( "lang", "und" )
:css( "margin-left", "1em" )
:css( "margin-right", "1em" )
:wikitext( string.format( "Q%d",
access ) ) )
end
if e then
r1 = { }
table.insert( r1, e )
if not r2 then
r2 = string.format( "#%d", access )
end
end
if q then
local f = function ( add, alien, attr )
e = Text.html( tostring( add ),
"dd",
false,
alien )
if attr then
e:attr( attr )
end
table.insert( r1, e )
end
s, slang = Present.wikibase( q, true )
if s then
f( s, slang )
end
if adjust.wikidata then
f( Present.facet( q.id ) )
end
if adjust.source then
Present.from( q, adjust, f )
end
if adjust.version or adjust.locally then
s = Data.find( q, "version", 1 )
if s then
e = mw.html.create( "code" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( s )
if type( source ) == "table" then
s = Present.failsafe( source, s )
if s then
e:newline()
:node( s )
end
end
f( e, "zxx", { dir = "ltr" } )
end
end
end
return r1, r2
end -- Present.features()
Present.final = function ( all, apply )
-- Present link to validated upstream source URL
-- Precondition:
-- all -- item object
-- apply -- string, with protected source URL, or not
-- Postcondition:
-- Returns mw.html object, or not
local r
if type( apply ) == "string" then
local source, q = Data.find( all, "source", 1 )
if source == apply then
local store = string.format( "Q%d", Data.resolve.upgrade.Q )
local show = mw.wikibase.getSitelink( store )
local slang
if show then
if not Config.slang then
Config.slang = mw.language.getContentLanguage()
:getCode()
:lower()
end
slang = Config.slang
else
store = Data.fetch( "host" )
if q[ store ] then
q = q[ store ]
if q[ 1 ] then
store = q[ 1 ].datavalue.value.id
show = Present.wikibase( store )
end
end
end
show = show or "Upgrade"
show = string.format( "[%s %s]", apply, show )
r = Text.html( show, "span", false, slang )
r = mw.html.create( "span" )
:node( Present.flag( "download" ) )
:newline()
:node( r )
end
end
return r
end -- Present.final()
Present.find = function ( all, appear )
-- Try to create doc URL link
-- Precondition:
-- all -- item object
-- appear -- link title
-- Postcondition:
-- Returns string
local r = appear
local i = 1
local url = true
local collection, q, s, s1, s2, slang, store, t
while url do
url, q = Data.find( all, "doc", i )
if url then
collection = collection or { }
slang = false
if q then
store = store or Data.fetch( "doclang" )
if q[ store ] then
q = q[ store ]
for k = 1, #q do
t = q[ k ].datavalue.value
if t and t.id then
s = t.id
s1 = s1 or Data.fetch( "iso6391" )
t = mw.wikibase.getBestStatements( s, s1 )
if t[ 1 ] then
slang = t[ 1 ].mainsnak.datavalue.value
else
s2 = s2 or Data.fetch( "iso6392" )
t = mw.wikibase.getBestStatements( s,
s2 )
slang = t[ 1 ].mainsnak.datavalue.value
end
end
end -- k = 1, #q
end
end
slang = slang or "und"
if not collection[ slang ] then
collection[ slang ] = url
end
end
i = i + 1
end -- while q
if collection then
s = Text.find( collection )
if s then
r = string.format( "[%s %s]", s, r )
end
end
return r
end -- Present.find()
Present.flag = function ( ask )
-- Create icon
-- Postcondition:
-- Returns mw.html object
if not Present[ ask ] then
local c = Config.icons[ ask ]
local e = mw.html.create( "span" )
:attr( { ["aria-hidden"] = "true",
role = "presentation" } )
local s = string.format( "[[File:%s|%dpx|%s|%s]]",
c.source,
Config.icons.npx,
"class=noviewer",
c.support )
e:wikitext( s )
if Config.ltr then
s = "right"
else
s = "left"
end
e:css( "margin-" .. s, "1em" )
Present[ ask ] = e
end
return Present[ ask ]
end -- Present.flag()
Present.focus = function ( all )
-- Present one single item object
-- Precondition:
-- all -- item object
-- Postcondition:
-- Returns mw.html object
local r
if all and all.id then
local f = function ( add )
r:node( mw.html.create( "br" ) )
:newline()
:node( add )
end
local s, slang
r = mw.html.create( "div" )
:addClass( "plainlinks" )
:newline()
:node( Present.facet( all.id ) )
s, slang = Present.wikibase( all, false )
if s then
s = Present.find( all, s )
f( Text.html( s, "span", false, slang ) )
end
s, slang = Present.wikibase( all, true )
if s then
f( Text.html( s, "span", false, slang ) )
end
s = Data.find( all, "version", 1 )
if s then
f( mw.html.create( "code" )
:attr( "dir", "ltr" )
:wikitext( s ) )
end
if Data.father( all ) then
f( Present.father() )
else
s = Present.final( all, Data.final( all ) )
if s then
f( s )
end
end
r:newline()
end
return r
end -- Present.focus()
Present.fresh = function ( all, area )
-- Check whether local source code (copy) is present
-- Precondition:
-- all -- item object
-- area -- number, of namespace
-- Postcondition:
-- Returns
-- title object, if appropriate
-- string, if error message
-- nil, if not found
local r, s
if all.sitelinks then
local wiki
Config.site = Config.site or mw.wikibase.getGlobalSiteId()
wiki = all.sitelinks[ Config.site ]
if wiki and wiki.title then
r = found( wiki.title, area )
if type( r ) == "string" then
s = "err_SourceSitelink"
end
end
end
if not r then
r = Data.find( all, "source", 1 )
if r then
r = r:match( "^https://[^/]+/wiki/(.+:.+)$" )
if r then
r = found( r, area )
s = type( r )
if s == "string" then
s = "err_SourceWikidataBad"
elseif s == "table" then
s = false
else
s = "err_SourceUnregistered"
end
else
s = "err_SourceWikidataInvalid"
end
end
end
if s then
s = fault( Text.flip( s ) )
if type( r ) == "string" then
local e = mw.html.create( "em" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( r:gsub( "//", "//" ) )
r = string.format( "%s %s", s, tostring( e ) )
else
r = s
end
end
return r
end -- Present.fresh()
Present.from = function ( all, adjust, apply )
-- Present link to validated upstream source URL
-- Precondition:
-- all -- item object
-- adjust -- table, with options
-- .host -- show info about global source host
-- apply -- function, to drop result lines
local source, q = Data.find( all, "source", 1 )
if type( source ) == "string" then
local s = Data.final( all )
if s == source then
local seek = "^https://([^/ ]+%.org)/wiki/(%S*)$"
local e, site
site, s = source:match( seek )
if s then
local f = function ()
return mw.html.create( "span" )
:css( { display = "inline-block",
width = "2em" } )
:wikitext( " " )
end
s = string.format( "[%s %s]", source, s )
e = mw.html.create( "span" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( s )
if source:find( Config.from() .. "/wiki/" ) == 1 then
e:newline()
:node( f() )
:newline()
:node( Present.father() )
q = false
end
apply( e )
if q and adjust.host then
local ex, slang
s = string.format( "[https://%s/ %s]", site, site )
e = mw.html.create( "em" )
:attr( "dir", "ltr" )
:attr( "lang", "zxx" )
:wikitext( s )
s = Data.fetch( "host" )
if q[ s ] then
q = q[ s ]
if q[ 1 ] then
ex = q[ 1 ].datavalue.value.id
s, slang = Present.wikibase( ex, true )
if s then
e = mw.html.create( "span" )
:node( e )
:newline()
:node( f() )
:newline()
:node( Text.html( s,
"span",
false,
slang ) )
end
end
end
apply( e )
end
end
end
elseif s then
apply( fault( Text.flip( "err_SourceUnregistered" ) ) )
end
end -- Present.from()
Present.full = function ( array, adjust )
-- Description list of entire area
-- Precondition:
-- array -- table, with non-empty sequence of item numbers
-- adjust -- table, with options
-- Postcondition:
-- Returns mw.html object, or not
local entries = { }
local order = { }
local entry, r, sort
for i = 1, #array do
entry, sort = Present.features( array[ i ], adjust )
if entry then
entries[ sort ] = entry
table.insert( order, sort )
end
end -- for i
if #order then
r = mw.html.create( "dl" )
:addClass( "plainlinks" )
if not adjust.lazy then
table.sort( order )
end
for i = 1, #order do
entry = entries[ order[ i ] ]
for k = 1, #entry do
r:newline()
:node( entry[ k ] )
end -- for k
end -- for i
Text.fashion( r, adjust )
Text.flow( r )
if type( adjust.id ) == "string" then
r:attr( "id", adjust.id )
end
r:newline()
end
return r
end -- Present.full()
Present.wikibase = function ( all, about, attempt )
-- Translation of wikibase component
-- Precondition:
-- all -- string or table, object ID or entity
-- about -- boolean, true "descriptions" or false "labels"
-- attempt -- string or not, code of preferred language
-- Postcondition:
-- Returns
-- 1. string, with selected message, or not
-- 2. string, with language code, or not
local r1, r2
if Present.Multilingual then
r1, r2 = Present.Multilingual.wikibase( all,
about,
attempt,
Config.frame )
else
local s = type( all )
local object
if s == "table" then
object = all
elseif s == "string" then
if mw.wikibase.isValidEntityId( all ) and
mw.wikibase.entityExists( all ) then
object = mw.wikibase.getEntity( all )
end
r1 = all
end
if type( object ) == "table" then
if about then
s = "descriptions"
else
s = "labels"
end
object = object[ s ]
if type( object ) == "table" then
if object[ attempt ] then
r1 = object[ attempt ].value
r2 = attempt
elseif object.en then
r1 = object.en.value
r2 = "en"
else
local poly
for k, v in pairs( object ) do
r1 = v.value
r2 = k
break -- for k, v
end -- for k, v
end
end
end
end
return r1 or "????????", r2
end -- Present.wikibase()
local Collection = function ( action, area, add )
-- Present all registered shared things in one area
-- Precondition:
-- action -- false->"full" or true->"fresh"
-- area -- number, nonzero, of area
-- add -- table, with options, or not
-- Postcondition:
-- Returns string, HTML code
local r
Config.first()
if type( area ) == "number" and area ~= 0 then
local q
if type( add ) == "table" and
type( add.items ) == "string" then
q = mw.text.split( add.items, "%s+" )
for i = 1, #q do
q[ i ] = tonumber( q[ i ] )
end -- for i
else
q = Data.full( area )
end
if q then
local o = { }
if type( add ) == "table" then
for k, v in pairs( add ) do
if v ~= "0" and v ~= "-" then
o[ k ] = v
end
end -- for k, v
end
if action then
o.linksite = true
if area == 10 or area == 828 then
o.locally = true
end
elseif area == 4 then
o.lazy = true
o.linksite = true
o.locally = true
end
o.namespace = area
if o.version or o.source then
o.wikidata = true
end
r = Present.full( q, o )
if r then
r = tostring( r )
end
else
r = fault( Text.flip( "err_CollectionUnknown" ) )
end
else
r = fault( Text.flip( "err_CollectionInvalid" ) )
end
return r or ""
end -- Collection()
GlobalSharing.fetch = function ( access )
-- Retrieve item object
-- Precondition:
-- access -- string, or number, of item
-- Postcondition:
-- Returns table -- with item object
-- string -- with missing item ID
-- false -- if not appropriate
local s = type( access )
local r
if s == "number" and
access > 0 and
math.floor( access ) == access then
r = string.format( "Q%d", access )
elseif s == "string" and
access:match( "^Q[1-9]%d*$" ) then
r = access
end
if r and
mw.wikibase.isValidEntityId( r ) and
mw.wikibase.entityExists( r ) then
r = mw.wikibase.getEntity( r )
end
return r or false
end -- GlobalSharing.fetch()
GlobalSharing.focus = function ( access )
-- Present one single item object
-- Precondition:
-- access -- string, or number, of item
-- Postcondition:
-- Returns table -- with item object
-- false -- if not appropriate
local q = GlobalSharing.fetch( access )
local r
if type( q ) == "table" then
Config.first()
r = Present.focus( q )
end
return r or false
end -- GlobalSharing.focus()
GlobalSharing.fresh = function ( area, add )
-- Present state of local pages of registered transcludes
-- Precondition:
-- area -- number, nonzero, of area
-- add -- table, with options, or not
-- Postcondition:
-- Returns string, HTML code
return Collection( true, area, add )
end -- GlobalSharing.fresh()
GlobalSharing.full = function ( area, add )
-- Present all registered shared things in one area
-- Precondition:
-- area -- number, nonzero, of area
-- add -- table, with options, or not
-- Postcondition:
-- Returns string, HTML code
return Collection( false, area, add )
end -- GlobalSharing.full()
local Template = function ( action, frame )
local params = { }
local f = function ( a )
for k, v in pairs( a.args ) do
if type( v ) == "string" then
v = mw.text.trim( v )
if v ~= "" and v ~= "-" then
if type( k ) == "number" then
k = tostring( k )
end
params[ k ] = v
end
end
end -- for k, v
end
local lucky, plus, r, s
Config.frame = frame
f( frame )
f( frame:getParent() )
s = params[ "1" ]
if action == "focus" then
if s then
if s:match( "^Q[1-9]%d*$" ) then
elseif s:match( "^[1-9]%d*$" ) then
s = "Q" .. s
else
s = false
end
else
s = mw.wikibase.getEntityIdForCurrentPage()
end
lucky = s
elseif s and s:match( "^[1-9]%d*$" ) then
s = tonumber( s )
lucky = s
if action == "full" then
local i, sp
for k, v in pairs( params ) do
if Data.resolve[ k ] then
sp = k
else
i = k:match( "^P?([1-9]%d+)$" )
if i then
i = tonumber( i )
for kk, vv in pairs( Data.resolve ) do
if vv.P == i or vv.Q == i then
sp = kk
break -- for kk, vv
end
end -- for kk, vv
end
end
if sp then
plus = plus or { }
if v ~= "0" then
plus[ sp ] = true
end
sp = false
end
end -- for k, v
-- version=
-- P348=
-- 348=
end
end
if lucky then
lucky, r = pcall( GlobalSharing[ action ], s, plus )
if type( r ) == "table" then
r = tostring( r )
end
if r then
s = params[ "wrap" ]
if s and s:find( "$1", 1, true ) then
r = s:gsub( "$1", r )
end
end
end
return r or ""
end -- Template()
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.focus = function ( frame )
return Template( "focus", frame )
end -- p.focus
p.fresh = function ( frame )
return Template( "fresh", frame )
end -- p.fresh
p.full = function ( frame )
return Template( "full", frame )
end -- p.full
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.GlobalSharing = function ()
return GlobalSharing
end -- p.GlobalSharing
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.