Zeile 1: |
Zeile 1: |
| local TemplateData = { suite = "TemplateData", | | local TemplateData = { suite = "TemplateData", |
− | serial = "2018-02-11T1645", | + | serial = "2020-08-23", |
| item = 46997995 } | | item = 46997995 } |
| --[=[ | | --[=[ |
| improve template:TemplateData | | improve template:TemplateData |
| ]=] | | ]=] |
| + | local Failsafe = TemplateData |
| | | |
| | | |
Zeile 28: |
Zeile 29: |
| helpURL = "support4url", | | helpURL = "support4url", |
| helpUser = "support4wiki-user-name", | | helpUser = "support4wiki-user-name", |
− | msgDescMiss = "solo" }, | + | msgDescMiss = "solo", |
| + | tStylesTOCnum = "stylesTOCnum" }, |
| -- classParams = "classTable", | | -- classParams = "classTable", |
| -- classTable = false, -- class for params table | | -- classTable = false, -- class for params table |
| + | debugmultilang = "C0C0C0", |
| loudly = false, -- show exported element, etc. | | loudly = false, -- show exported element, etc. |
| solo = false, -- complaint on missing description | | solo = false, -- complaint on missing description |
Zeile 39: |
Zeile 42: |
| subpage = false, -- pattern to identify subpage | | subpage = false, -- pattern to identify subpage |
| suffix = false, -- subpage creation scheme | | suffix = false, -- subpage creation scheme |
− | suppressTOCnum = false -- class for TOC number suppression | + | suppressTOCnum = false, -- class for TOC number suppression |
| + | jsonDebug = "json-code-lint" -- class for jsonDebug tool |
| } | | } |
| local Data = { | | local Data = { |
Zeile 53: |
Zeile 57: |
| params = false, -- table, exported parameters | | params = false, -- table, exported parameters |
| scream = false, -- error messages | | scream = false, -- error messages |
− | slang = false, -- project language code | + | sibling = false, -- TOC juxtaposed |
| + | slang = nil, -- project/user language code |
| slim = false, -- JSON reduced to plain | | slim = false, -- JSON reduced to plain |
| source = false, -- JSON input | | source = false, -- JSON input |
Zeile 62: |
Zeile 67: |
| } | | } |
| local Permit = { | | local Permit = { |
− | builder = { align = "block", | + | builder = { after = "block", |
| + | align = "block", |
| block = "block", | | block = "block", |
| compressed = "block", | | compressed = "block", |
Zeile 72: |
Zeile 78: |
| last = "block", | | last = "block", |
| lead = "block", | | lead = "block", |
− | newlines = "block", | + | newlines = "*", |
| spaced = "inline" }, | | spaced = "inline" }, |
| colors = { tableheadbg = "B3B7FF", | | colors = { tableheadbg = "B3B7FF", |
Zeile 82: |
Zeile 88: |
| autovalue = "string", | | autovalue = "string", |
| default = "string table I18N nowiki", | | default = "string table I18N nowiki", |
− | deprecated = "boolean string", | + | deprecated = "boolean string I18N", |
| description = "string table I18N", | | description = "string table I18N", |
| example = "string table I18N nowiki", | | example = "string table I18N nowiki", |
Zeile 88: |
Zeile 94: |
| inherits = "string", | | inherits = "string", |
| required = "boolean", | | required = "boolean", |
| + | style = "string table", |
| suggested = "boolean", | | suggested = "boolean", |
| type = "string" }, | | type = "string" }, |
Zeile 130: |
Zeile 137: |
| | | |
| | | |
− | local function Fetch( ask ) | + | local function Fetch( ask, allow ) |
| -- Fetch module | | -- Fetch module |
| -- Parameter: | | -- Parameter: |
− | -- ask -- string, with name | + | -- ask -- string, with name |
− | -- "Multilingual" | + | -- "/global" |
− | -- "Text" | + | -- "JSONutil" |
− | -- "WLink" | + | -- "Multilingual" |
| + | -- "Text" |
| + | -- "WLink" |
| + | -- allow -- true: no error if unavailable |
| -- Returns table of module | | -- Returns table of module |
| -- error: Module not available | | -- error: Module not available |
− | local r | + | local sign = ask |
| + | local r, stem |
| + | if sign:sub( 1, 1 ) == "/" then |
| + | sign = TemplateData.frame:getTitle() .. sign |
| + | else |
| + | stem = sign |
| + | sign = "Module:" .. stem |
| + | end |
| if TemplateData.extern then | | if TemplateData.extern then |
− | r = TemplateData.extern[ ask ] | + | r = TemplateData.extern[ sign ] |
| else | | else |
| TemplateData.extern = { } | | TemplateData.extern = { } |
| end | | end |
| if not r then | | if not r then |
− | local lucky, g = pcall( require, "Module:" .. ask ) | + | local lucky, g = pcall( require, sign ) |
| if type( g ) == "table" then | | if type( g ) == "table" then |
− | r = g[ ask ]() | + | if stem and type( g[ stem ] ) == "function" then |
− | TemplateData.extern[ ask ] = r | + | r = g[ stem ]() |
− | else | + | else |
− | error( string.format( "Fetch(%s) %s", ask, g ) ) | + | r = g |
| + | end |
| + | TemplateData.extern[ sign ] = r |
| + | elseif not allow then |
| + | error( string.format( "Fetch(%s) %s", sign, g ), 0 ) |
| end | | end |
| end | | end |
| return r | | return r |
| end -- Fetch() | | end -- Fetch() |
| + | |
| + | |
| + | |
| + | local function Foreign() |
| + | -- Guess human language |
| + | -- Returns slang, or not |
| + | if type( Data.slang ) == "nil" then |
| + | local Multilingual = Fetch( "Multilingual", true ) |
| + | if Multilingual and |
| + | type( Multilingual.userLangCode ) == "function" then |
| + | Data.slang = Multilingual.userLangCode() |
| + | else |
| + | Data.slang = mw.language.getContentLanguage():getCode() |
| + | :lower() |
| + | end |
| + | end |
| + | if Data.slang and |
| + | mw.ustring.codepoint( Data.slang, 1, 1 ) > 122 then |
| + | Data.slang = false |
| + | end |
| + | return Data.slang |
| + | end -- Foreign() |
| | | |
| | | |
Zeile 194: |
Zeile 237: |
| -- adapt -- string, message ID after "templatedata-" | | -- adapt -- string, message ID after "templatedata-" |
| -- Returns string, with localized text | | -- Returns string, with localized text |
− | return mw.message.new( "templatedata-" .. adapt ):plain() | + | local o = mw.message.new( "templatedata-" .. adapt ) |
| + | if Foreign() then |
| + | o:inLanguage( Data.slang ) |
| + | end |
| + | return o:plain() |
| end -- factory() | | end -- factory() |
| | | |
Zeile 274: |
Zeile 321: |
| return r | | return r |
| end -- fair() | | end -- fair() |
| + | |
| + | |
| + | |
| + | |
| + | local function fancy( advance, alert ) |
| + | -- Present JSON source |
| + | -- Parameter: |
| + | -- advance -- true, for nice |
| + | -- alert -- true, for visible |
| + | -- Returns string |
| + | local r |
| + | if Data.source then |
| + | local support = Config.jsonDebug |
| + | local css |
| + | if advance then |
| + | css = { height = "6em", |
| + | resize = "vertical" } |
| + | r = { [ 1 ] = "syntaxhighlight", |
| + | [ 2 ] = Data.source, |
| + | lang = "json", |
| + | style = table.concat( css, ";" ) } |
| + | if alert then |
| + | r.class( support ) |
| + | end |
| + | r = TemplateData.frame:callParserFunction( "#tag", r ) |
| + | else |
| + | css = { [ "font-size" ] = "77%", |
| + | [ "line-height" ] = "1.35" } |
| + | if alert then |
| + | css.resize = "vertical" |
| + | else |
| + | css.display = "none" |
| + | end |
| + | r = mw.html.create( "pre" ) |
| + | :addClass( support ) |
| + | :css( css ) |
| + | :wikitext( mw.text.encode( Data.source ) ) |
| + | r = tostring( r ) |
| + | end |
| + | r = "\n".. r |
| + | else |
| + | r = "" |
| + | end |
| + | return r |
| + | end -- fancy() |
| | | |
| | | |
| | | |
| local function faraway( alternatives ) | | local function faraway( alternatives ) |
− | -- Retrieve project language version from multilingual text | + | -- Retrieve best language version from multilingual text |
| -- Parameter: | | -- Parameter: |
| -- alternatives -- table, to be evaluated | | -- alternatives -- table, to be evaluated |
Zeile 287: |
Zeile 379: |
| local variants = { } | | local variants = { } |
| local r1, r2 | | local r1, r2 |
− | if not Data.slang then
| |
− | Data.slang = mw.language.getContentLanguage():getCode()
| |
− | end
| |
| for k, v in pairs( alternatives ) do | | for k, v in pairs( alternatives ) do |
| if type( v ) == "string" then | | if type( v ) == "string" then |
| v = mw.text.trim( v ) | | v = mw.text.trim( v ) |
− | if v ~= "" then | + | if v ~= "" and type( k ) == "string" then |
| + | k = k:lower() |
| variants[ k ] = v | | variants[ k ] = v |
| n = n + 1 | | n = n + 1 |
Zeile 300: |
Zeile 390: |
| end -- for k, v | | end -- for k, v |
| if n > 0 then | | if n > 0 then |
− | for k, v in pairs( variants ) do | + | local Multilingual = Fetch( "Multilingual", true ) |
− | if v then | + | if Multilingual and |
− | if n == 1 then | + | type( Multilingual.i18n ) == "function" then |
− | r1 = v
| + | local show, slang = Multilingual.i18n( variants ) |
− | elseif k:lower() == Data.slang then | + | if show then |
− | variants[ k ] = nil
| + | r1 = show |
− | r1 = v
| + | variants[ slang ] = nil |
− | r2 = variants
| + | r2 = variants |
− | break -- for k, v
| |
− | end
| |
| end | | end |
− | end -- for k, v | + | end |
| if not r1 then | | if not r1 then |
− | local seek = string.format( "^%s-", Data.slang ) | + | Foreign() |
| for k, v in pairs( variants ) do | | for k, v in pairs( variants ) do |
− | if v and k:lower():match( seek ) then | + | if n == 1 then |
| + | r1 = v |
| + | elseif Data.slang == k then |
| variants[ k ] = nil | | variants[ k ] = nil |
| r1 = v | | r1 = v |
| r2 = variants | | r2 = variants |
− | break -- for k, v
| |
| end | | end |
| end -- for k, v | | end -- for k, v |
− | if not r1 then
| |
− | local others = mw.language.getFallbacksFor( slang )
| |
− | table.insert( others, "en" )
| |
− | for i = 1, #others do
| |
− | seek = others[ i ]
| |
− | if variants[ seek ] then
| |
− | r1 = variants[ seek ]
| |
− | variants[ seek ] = nil
| |
− | r2 = variants
| |
− | break -- for i
| |
− | end
| |
− | end -- i = 1, #others
| |
− | end
| |
− | if not r1 then
| |
− | for k, v in pairs( variants ) do
| |
− | if v then
| |
− | variants[ k ] = nil
| |
− | r1 = v
| |
− | r2 = variants
| |
− | break -- for k, v
| |
− | end
| |
− | end -- for k, v
| |
− | end
| |
| end | | end |
− | if r2 then | + | if r2 and Multilingual then |
− | local Multilingual = Fetch( "Multilingual" )
| |
| for k, v in pairs( r2 ) do | | for k, v in pairs( r2 ) do |
− | if v and not Multilingual.isLang( k ) then | + | if v and not Multilingual.isLang( k, true ) then |
− | Fault( string.format( "Invalid <code>lang=%s</code>", | + | Fault( string.format( "%s <code>lang=%s</code>", |
| + | "Invalid", |
| k ) ) | | k ) ) |
| end | | end |
Zeile 358: |
Zeile 424: |
| return r1, r2 | | return r1, r2 |
| end -- faraway() | | end -- faraway() |
| + | |
| + | |
| + | |
| + | local function fashioned( about, asked, assign ) |
| + | -- Create description head |
| + | -- Parameter: |
| + | -- about -- table, supposed to contain description |
| + | -- asked -- true, if mandatory description |
| + | -- assign -- <block>, if to be equipped |
| + | -- Returns <block>, with head, or nil |
| + | local para = assign or mw.html.create( "div" ) |
| + | local plus, r |
| + | if about and about.description then |
| + | if type( about.description ) == "string" then |
| + | para:wikitext( about.description ) |
| + | else |
| + | para:wikitext( about.description[ 1 ] ) |
| + | plus = mw.html.create( "ul" ) |
| + | plus:css( "text-align", "left" ) |
| + | for k, v in pairs( about.description[ 2 ] ) do |
| + | plus:node( mw.html.create( "li" ) |
| + | :node( mw.html.create( "code" ) |
| + | :wikitext( k ) ) |
| + | :node( mw.html.create( "br" ) ) |
| + | :wikitext( fair( v ) ) ) |
| + | end -- for k, v |
| + | if Config.loudly then |
| + | plus = mw.html.create( "div" ) |
| + | :css( "background-color", |
| + | "#" .. Config.debugmultilang ) |
| + | :node( plus ) |
| + | else |
| + | plus:addClass( "templatedata-maintain" ) |
| + | :css( "display", "none" ) |
| + | end |
| + | end |
| + | elseif Config.solo and asked then |
| + | para:addClass( "error" ) |
| + | :wikitext( Config.solo ) |
| + | Data.less = true |
| + | else |
| + | para = false |
| + | end |
| + | if para then |
| + | if plus then |
| + | r = mw.html.create( "div" ) |
| + | :node( para ) |
| + | :node( plus ) |
| + | else |
| + | r = para |
| + | end |
| + | end |
| + | return r |
| + | end -- fashioned() |
| + | |
| + | |
| + | |
| + | local function fatten( access ) |
| + | -- Create table row for sub-headline |
| + | -- Parameter: |
| + | -- access -- string, with name |
| + | -- Returns <tr> |
| + | local param = Data.tree.params[ access ] |
| + | local sub, sort = access:match( "(=+)%s*(%S.*)$" ) |
| + | local headline = mw.html.create( string.format( "h%d", #sub ) ) |
| + | local r = mw.html.create( "tr" ) |
| + | local td = mw.html.create( "td" ) |
| + | :attr( "colspan", "5" ) |
| + | :attr( "data-sort-value", "!" .. sort ) |
| + | local s |
| + | if param.style then |
| + | s = type( param.style ) |
| + | if s == "table" then |
| + | td:css( param.style ) |
| + | elseif s == "string" then |
| + | td:cssText( param.style ) |
| + | end |
| + | end |
| + | s = fashioned( param, false, headline ) |
| + | if s then |
| + | headline = s |
| + | else |
| + | headline:wikitext( sort ) |
| + | end |
| + | td:node( headline ) |
| + | r:node( td ) |
| + | return r |
| + | end -- fatten() |
| | | |
| | | |
Zeile 371: |
Zeile 525: |
| end -- for k, v | | end -- for k, v |
| for i = 1, n do | | for i = 1, n do |
− | for k, v in pairs( Data.heirs ) do | + | if Data.heirs then |
− | if v and not Data.heirs[ v ] then
| + | for k, v in pairs( Data.heirs ) do |
− | n = n - 1
| + | if v and not Data.heirs[ v ] then |
− | t[ k ].inherits = nil
| + | n = n - 1 |
− | Data.heirs[ k ] = nil
| + | t[ k ].inherits = nil |
− | p2 = { }
| + | Data.heirs[ k ] = nil |
− | t2 = { }
| + | p2 = { } |
− | for k2, v2 in pairs( p[ v ] ) do
| + | t2 = { } |
− | p2[ k2 ] = v2 | + | if p[ v ] then |
− | end -- for k2, v2
| + | for k2, v2 in pairs( p[ v ] ) do |
− | if p[ k ] then
| |
− | for k2, v2 in pairs( p[ k ] ) do
| |
− | if type( v2 ) ~= "nil" then
| |
| p2[ k2 ] = v2 | | p2[ k2 ] = v2 |
| + | end -- for k2, v2 |
| + | if p[ k ] then |
| + | for k2, v2 in pairs( p[ k ] ) do |
| + | if type( v2 ) ~= "nil" then |
| + | p2[ k2 ] = v2 |
| + | end |
| + | end -- for k2, v2 |
| end | | end |
− | end -- for k2, v2
| + | p[ k ] = p2 |
| + | for k2, v2 in pairs( t[ v ] ) do |
| + | t2[ k2 ] = v2 |
| + | end -- for k2, v2 |
| + | for k2, v2 in pairs( t[ k ] ) do |
| + | if type( v2 ) ~= "nil" then |
| + | t2[ k2 ] = v2 |
| + | end |
| + | end -- for k2, v2 |
| + | t[ k ] = t2 |
| + | else |
| + | Fault( "No params[] inherits " .. v ) |
| + | end |
| end | | end |
− | p[ k ] = p2
| + | end -- for k, v |
− | for k2, v2 in pairs( t[ v ] ) do
| + | end |
− | t2[ k2 ] = v2
| |
− | end -- for k2, v2
| |
− | for k2, v2 in pairs( t[ k ] ) do
| |
− | if type( v2 ) ~= "nil" then
| |
− | t2[ k2 ] = v2
| |
− | end
| |
− | end -- for k2, v2
| |
− | t[ k ] = t2
| |
− | end
| |
− | end -- for k, v | |
| end -- i = 1, n | | end -- i = 1, n |
| if n > 0 then | | if n > 0 then |
Zeile 470: |
Zeile 630: |
| end -- for k, v | | end -- for k, v |
| end | | end |
− | end -- favorize()
| + | if type( Config.subpage ) ~= "string" or |
− | | + | type( Config.suffix ) ~= "string" then |
− | | + | local got = mw.message.new( "templatedata-doc-subpage" ) |
− | | + | local suffix |
− | local function feasible( about, asked )
| + | if got:isDisabled() then |
− | -- Create description head
| + | suffix = "doc" |
− | -- Parameter:
| |
− | -- about -- table, supposed to contain description
| |
− | -- asked -- true, if mandatory description
| |
− | -- Returns <block>, with head, or nil
| |
− | local para = mw.html.create( "div" )
| |
− | local plus, r
| |
− | if about and about.description then
| |
− | if type( about.description ) == "string" then | |
− | para:wikitext( about.description )
| |
| else | | else |
− | para:wikitext( about.description[ 1 ] ) | + | suffix = got:plain() |
− | plus = mw.html.create( "ul" )
| + | end |
− | if not Config.loudly then
| + | if type( Config.subpage ) ~= "string" then |
− | plus:addClass( "templatedata-maintain" )
| + | Config.subpage = string.format( "/%s$", suffix ) |
− | :css( "display", "none" )
| |
− | end | |
− | for k, v in pairs( about.description[ 2 ] ) do
| |
− | plus:node( mw.html.create( "li" )
| |
− | :node( mw.html.create( "code" )
| |
− | :wikitext( k ) )
| |
− | :node( mw.html.create( "br" ) )
| |
− | :wikitext( fair( v ) ) )
| |
− | end -- for k, v
| |
| end | | end |
− | elseif Config.solo and asked then
| + | if type( Config.suffix ) ~= "string" then |
− | para:addClass( "error" ) | + | Config.suffix = string.format( "%%s/%s", suffix ) |
− | :wikitext( Config.solo )
| |
− | Data.less = true
| |
− | else
| |
− | para = false
| |
− | end
| |
− | if para then
| |
− | if plus then
| |
− | r = mw.html.create( "div" ) | |
− | :node( para )
| |
− | :node( plus )
| |
− | else
| |
− | r = para
| |
| end | | end |
| end | | end |
− | return r
| + | end -- favorize() |
− | end -- feasible() | |
| | | |
| | | |
Zeile 539: |
Zeile 668: |
| local pointers = { } | | local pointers = { } |
| local points = { } | | local points = { } |
| + | local given = { } |
| for k, v in pairs( Data.tree.params ) do | | for k, v in pairs( Data.tree.params ) do |
| i = facet( k, 1 ) | | i = facet( k, 1 ) |
| + | if type( v ) == "table" then |
| + | if type( v.label ) == "string" then |
| + | s = mw.text.trim( v.label ) |
| + | if s == "" then |
| + | s = k |
| + | end |
| + | else |
| + | s = k |
| + | end |
| + | if given[ s ] then |
| + | if given[ s ] == 1 then |
| + | local scream = "Parameter label '%s' detected multiple times" |
| + | Fault( string.format( scream, s ) ) |
| + | given[ s ] = 2 |
| + | end |
| + | else |
| + | given[ s ] = 1 |
| + | end |
| + | end |
| if i then | | if i then |
| table.insert( points, i ) | | table.insert( points, i ) |
Zeile 647: |
Zeile 796: |
| | | |
| -- description etc. | | -- description etc. |
− | s = feasible( param ) | + | s = fashioned( param ) |
| if s then | | if s then |
| desc:node( s ) | | desc:node( s ) |
| + | end |
| + | if param.style then |
| + | s = type( param.style ) |
| + | if s == "table" then |
| + | desc:css( param.style ) |
| + | elseif s == "string" then |
| + | desc:cssText( param.style ) |
| + | end |
| end | | end |
| if param.default or param.example or param.autovalue then | | if param.default or param.example or param.autovalue then |
Zeile 671: |
Zeile 828: |
| if type( boole.show ) == "string" then | | if type( boole.show ) == "string" then |
| local v = mw.html.create( "span" ) | | local v = mw.html.create( "span" ) |
| + | :attr( "aria-hidden", "true" ) |
| :wikitext( boole.show ) | | :wikitext( boole.show ) |
| if boole.css then | | if boole.css then |
Zeile 697: |
Zeile 855: |
| | | |
| -- type | | -- type |
| + | if type( param.type ) == "string" then |
| + | param.type = mw.text.trim( param.type ) |
| + | if param.type == "" then |
| + | param.type = false |
| + | end |
| + | end |
| if param.type then | | if param.type then |
| s = Permit.types[ param.type ] | | s = Permit.types[ param.type ] |
Zeile 733: |
Zeile 897: |
| if param.required then | | if param.required then |
| mode = 1 | | mode = 1 |
| + | if param.autovalue then |
| + | Fault( string.format( "autovalued <code>%s</code> required", |
| + | access ) ) |
| + | legal = false |
| + | end |
| + | if param.default then |
| + | Fault( string.format( "Defaulted <code>%s</code> required", |
| + | access ) ) |
| + | legal = false |
| + | end |
| if param.deprecated then | | if param.deprecated then |
| Fault( string.format( "Required deprecated <code>%s</code>", | | Fault( string.format( "Required deprecated <code>%s</code>", |
Zeile 781: |
Zeile 955: |
| local r | | local r |
| if Data.tree and Data.tree.params then | | if Data.tree and Data.tree.params then |
− | local tbl = mw.html.create( "table" ) | + | local tbl = mw.html.create( "table" ) |
− | :addClass( "wikitable" )
| + | :addClass( "wikitable" ) |
− | local tr = mw.html.create( "tr" ) | + | local tr = mw.html.create( "tr" ) |
| feat() | | feat() |
| if Data.order and #Data.order > 1 then | | if Data.order and #Data.order > 1 then |
Zeile 818: |
Zeile 992: |
| :newline() | | :newline() |
| if Data.order then | | if Data.order then |
| + | local leave, s |
| for i = 1, #Data.order do | | for i = 1, #Data.order do |
− | tbl:node( feature( Data.order[ i ] ) ) | + | s = Data.order[ i ] |
| + | if s:sub( 1, 1 ) == "=" then |
| + | leave = true |
| + | tbl:node( fatten( s ) ) |
| + | Data.order[ i ] = false |
| + | elseif s:match( "[=|]" ) then |
| + | Fault( string.format( "Bad param <code>%s</code>", |
| + | s ) ) |
| + | else |
| + | tbl:node( feature( s ) ) |
| + | end |
| end -- for i = 1, #Data.order | | end -- for i = 1, #Data.order |
| + | if leave then |
| + | for i = #Data.order, 1, -1 do |
| + | if not Data.order[ i ] then |
| + | table.remove( Data.order, i ) |
| + | end |
| + | end -- for i = #Data.order, 1, -1 |
| + | end |
| + | Data.tag.paramOrder = Data.order |
| end | | end |
− | if Config.cssTabWrap then | + | if Config.cssTabWrap or Data.scroll then |
| r = mw.html.create( "div" ) | | r = mw.html.create( "div" ) |
| if type( Config.cssTabWrap ) == "table" then | | if type( Config.cssTabWrap ) == "table" then |
Zeile 829: |
Zeile 1.022: |
| -- deprecated | | -- deprecated |
| r:cssText( Config.cssTabWrap ) | | r:cssText( Config.cssTabWrap ) |
| + | end |
| + | if Data.scroll then |
| + | r:css( "height", Data.scroll ) |
| + | :css( "overflow", "auto" ) |
| end | | end |
| r:node( tbl ) | | r:node( tbl ) |
Zeile 840: |
Zeile 1.037: |
| | | |
| | | |
− | local function finalize() | + | local function fellow( any, assigned, at ) |
| + | -- Check sets[] parameter and issue error message, if necessary |
| + | -- Parameter: |
| + | -- any -- should be number |
| + | -- assigned -- parameter name |
| + | -- at -- number, of set |
| + | local s |
| + | if type( any ) ~= "number" then |
| + | s = "<code>sets[%d].params[%s]</code>??" |
| + | Fault( string.format( s, |
| + | at, |
| + | mw.text.nowiki( tostring( any ) ) ) ) |
| + | elseif type( assigned ) == "string" then |
| + | if not Data.got.params[ assigned ] then |
| + | s = "<code>sets[%d].params %s</code> is undefined" |
| + | Fault( string.format( s, at, assigned ) ) |
| + | end |
| + | else |
| + | s = "<code>sets[%d].params[%d] = %s</code>??" |
| + | Fault( string.format( s, k, type( assigned ) ) ) |
| + | end |
| + | end -- fellow() |
| + | |
| + | |
| + | |
| + | local function fellows() |
| + | -- Check sets[] and issue error message, if necessary |
| + | local s |
| + | if type( Data.got.sets ) == "table" then |
| + | if type( Data.got.params ) == "table" then |
| + | for k, v in pairs( Data.got.sets ) do |
| + | if type( k ) == "number" then |
| + | if type( v ) == "table" then |
| + | for ek, ev in pairs( v ) do |
| + | if ek == "label" then |
| + | s = type( ev ) |
| + | if s ~= "string" and |
| + | s ~= "table" then |
| + | s = "<code>sets[%d].label</code>??" |
| + | Fault( string.format( s, k ) ) |
| + | end |
| + | elseif ek == "params" and |
| + | type( ev ) == "table" then |
| + | for pk, pv in pairs( ev ) do |
| + | fellow( pk, pv, k ) |
| + | end -- for pk, pv |
| + | else |
| + | ek = mw.text.nowiki( tostring( ek ) ) |
| + | s = "<code>sets[%d][%s]</code>??" |
| + | Fault( string.format( s, k, ek ) ) |
| + | end |
| + | end -- for ek, ev |
| + | else |
| + | k = mw.text.nowiki( tostring( k ) ) |
| + | v = mw.text.nowiki( tostring( v ) ) |
| + | s = string.format( "<code>sets[%s][%s]</code>??", |
| + | k, v ) |
| + | Fault( s ) |
| + | end |
| + | else |
| + | k = mw.text.nowiki( tostring( k ) ) |
| + | s = string.format( "<code>sets[%s]</code> ?????", k ) |
| + | Fault( s ) |
| + | end |
| + | end -- for k, v |
| + | else |
| + | s = "<code>params</code> required for <code>sets</code>" |
| + | Fault( s ) |
| + | end |
| + | else |
| + | s = "<code>sets</code> needs to be of <code>object</code> type" |
| + | Fault( s ) |
| + | end |
| + | end -- fellows() |
| + | |
| + | |
| + | |
| + | local function finalize( advance ) |
| -- Wrap presentation into frame | | -- Wrap presentation into frame |
| + | -- Parameter: |
| + | -- advance -- true, for nice |
| -- Returns string | | -- Returns string |
− | local r | + | local r, lapsus |
| if Data.div then | | if Data.div then |
| r = tostring( Data.div ) | | r = tostring( Data.div ) |
Zeile 849: |
Zeile 1.125: |
| r = Data.strip | | r = Data.strip |
| else | | else |
− | r = "" | + | lapsus = true |
| + | r = "" |
| + | end |
| + | r = r .. failures() |
| + | if Data.source then |
| + | local live = ( advance or lapsus ) |
| + | if not live then |
| + | live = TemplateData.frame:preprocess( "{{REVISIONID}}" ) |
| + | live = ( live == "" ) |
| + | end |
| + | if live then |
| + | r = r .. fancy( advance, lapsus ) |
| + | end |
| end | | end |
− | return r .. failures() | + | return r |
| end -- finalize() | | end -- finalize() |
| | | |
Zeile 889: |
Zeile 1.177: |
| if r:find( "<", 1, true ) then | | if r:find( "<", 1, true ) then |
| local Text = Fetch( "Text" ) | | local Text = Fetch( "Text" ) |
− | r = Text.getPlain( r ) | + | r = Text.getPlain( r:gsub( "<br */?>", "\r\n" ) ) |
| end | | end |
| if r:find( "[", 1, true ) then | | if r:find( "[", 1, true ) then |
Zeile 981: |
Zeile 1.269: |
| if s == "string" then | | if s == "string" then |
| elem = fair( v ) | | elem = fair( v ) |
− | else | + | elseif s == "table" then |
| local translated | | local translated |
| v, translated = faraway( v ) | | v, translated = faraway( v ) |
Zeile 996: |
Zeile 1.284: |
| end | | end |
| end | | end |
− | if v then | + | if type( v ) == "string" then |
− | if scope:find( "nowiki", 1, true ) then | + | if k == "deprecated" then |
| + | if v == "1" then |
| + | v = true |
| + | elseif v == "0" then |
| + | v = false |
| + | end |
| + | elem = v |
| + | elseif scope:find( "nowiki", 1, true ) then |
| elem = mw.text.nowiki( v ) | | elem = mw.text.nowiki( v ) |
| + | elem = elem:gsub( " \n", "<br>" ) |
| + | v = v:gsub( string.char( 13 ), "" ) |
| else | | else |
| v = flat( v ) | | v = flat( v ) |
| + | end |
| + | elseif s == "boolean" then |
| + | if scope:find( "boolean", 1, true ) then |
| + | elem = v |
| + | else |
| + | s = "Type <code>boolean</code> bad for " |
| + | .. f( k, slot ) |
| + | Fault( s ) |
| end | | end |
| end | | end |
Zeile 1.008: |
Zeile 1.313: |
| elem = nil | | elem = nil |
| elseif k == "format" and not access then | | elseif k == "format" and not access then |
− | v = mw.text.decode( v ) | + | elem = mw.text.decode( v ) |
− | elem = v | + | v = nil |
| elseif k == "inherits" then | | elseif k == "inherits" then |
| elem = v | | elem = v |
Zeile 1.017: |
Zeile 1.322: |
| Data.heirs[ slot ] = v | | Data.heirs[ slot ] = v |
| v = nil | | v = nil |
| + | elseif k == "style" then |
| + | elem = v |
| + | v = nil |
| elseif s == "string" then | | elseif s == "string" then |
| v = mw.text.nowiki( v ) | | v = mw.text.nowiki( v ) |
Zeile 1.043: |
Zeile 1.351: |
| if not tag then | | if not tag then |
| if access then | | if access then |
− | if not Data.params then | + | if type( v ) == "string" and |
− | Data.params = { } | + | v.sub( 1, 1 ) == "=" then |
| + | v = nil |
| + | else |
| + | if not Data.params then |
| + | Data.params = { } |
| + | end |
| + | Data.params[ slot ] = { } |
| + | tag = Data.params[ slot ] |
| end | | end |
− | Data.params[ slot ] = { }
| |
− | tag = Data.params[ slot ]
| |
| else | | else |
| Data.tag = { } | | Data.tag = { } |
Zeile 1.053: |
Zeile 1.366: |
| end | | end |
| end | | end |
− | tag[ k ] = v | + | if type( v ) ~= "nil" then |
| + | tag[ k ] = v |
| + | end |
| end | | end |
| else | | else |
Zeile 1.064: |
Zeile 1.379: |
| end | | end |
| end -- for k, v | | end -- for k, v |
| + | if not access and Data.got.sets then |
| + | fellows() |
| + | end |
| else | | else |
| Fault( f() .. " needs to be of <code>object</code> type" ) | | Fault( f() .. " needs to be of <code>object</code> type" ) |
Zeile 1.083: |
Zeile 1.401: |
| if source:find( "|", 1, true ) then | | if source:find( "|", 1, true ) then |
| local scan = "^[\n ]*%{%{[\n _]*|[\n _]*=[\n _]*%}%}[\n ]*$" | | local scan = "^[\n ]*%{%{[\n _]*|[\n _]*=[\n _]*%}%}[\n ]*$" |
− | if source:match( scan, 1, true ) then | + | if source:match( scan ) then |
| code = source:gsub( "\n", "N" ) | | code = source:gsub( "\n", "N" ) |
| else | | else |
Zeile 1.094: |
Zeile 1.412: |
| else | | else |
| local words = mw.text.split( source, "%s+" ) | | local words = mw.text.split( source, "%s+" ) |
− | local show, start, unknown | + | local show, start, support, unknown |
| for i = 1, #words do | | for i = 1, #words do |
| s = words[ i ] | | s = words[ i ] |
Zeile 1.100: |
Zeile 1.418: |
| start = s | | start = s |
| end | | end |
− | if Permit.builder[ s ] == start then | + | support = Permit.builder[ s ] |
| + | if support == start or |
| + | support == "*" then |
| Permit.builder[ s ] = true | | Permit.builder[ s ] = true |
| + | elseif s:match( "^[1-9]%d?" ) and |
| + | Permit.builder.align then |
| + | Permit.builder.align = tonumber( s ) |
| else | | else |
| if unknown then | | if unknown then |
Zeile 1.124: |
Zeile 1.447: |
| elseif Permit.builder.grouped == true then | | elseif Permit.builder.grouped == true then |
| show = "inline grouped" | | show = "inline grouped" |
− | code = "{{_ | _=_ }}" | + | code = "{{_ | _=_}}" |
| elseif Permit.builder.spaced == true then | | elseif Permit.builder.spaced == true then |
| show = "inline spaced" | | show = "inline spaced" |
| code = "{{_ | _ = _ }}" | | code = "{{_ | _ = _ }}" |
| + | end |
| + | if Permit.builder.newlines == true then |
| + | show = show or "inline" |
| + | code = code or "{{_|_=_}}" |
| + | show = show .. " newlines" |
| + | code = string.format( "N%sN", code ) |
| end | | end |
| elseif start == "block" then | | elseif start == "block" then |
− | local space = " " -- amid "|" and name | + | local space = "" -- amid "|" and name |
| local spaced = " " -- preceding "=" | | local spaced = " " -- preceding "=" |
| local spacer = " " -- following "=" | | local spacer = " " -- following "=" |
Zeile 1.142: |
Zeile 1.471: |
| end | | end |
| if Permit.builder.compressed == true then | | if Permit.builder.compressed == true then |
− | space = ""
| |
| spaced = "" | | spaced = "" |
| spacer = "" | | spacer = "" |
Zeile 1.153: |
Zeile 1.481: |
| else | | else |
| if Permit.builder.lead == true then | | if Permit.builder.lead == true then |
− | show = show .. " lead" | + | show = show .. " lead" |
− | else
| + | space = " " |
− | space = "" | |
| end | | end |
− | if Permit.builder.align == true then | + | if type( Permit.builder.align ) ~= "string" then |
− | if type( Data.got ) == "table" and
| + | local n |
− | type( Data.got.params ) == "table" then
| + | s = " align" |
− | local n = 0
| + | if Permit.builder.align == true then |
− | for k, v in pairs( Data.got.params ) do
| + | n = 0 |
− | if type( v ) == "table" and
| + | if type( Data.got ) == "table" and |
− | v.deprecated and
| + | type( Data.got.params ) == "table" then |
− | type( k ) == "string" and
| + | for k, v in pairs( Data.got.params ) do |
− | #k > n then
| + | if type( v ) == "table" and |
− | n = #k
| + | not v.deprecated and |
− | end
| + | type( k ) == "string" then |
− | end -- for k, v
| + | k = mw.ustring.len( k ) |
− | if n > 1 then | + | if k > n then |
− | spaced = string.rep( "_", n ) .. " " | + | n = k |
| + | end |
| + | end |
| + | end -- for k, v |
| + | end |
| + | else |
| + | n = Permit.builder.align |
| + | if type( n ) == "number" and n > 1 then |
| + | s = string.format( "%s %d", s, n ) |
| + | else |
| + | n = 0 -- How comes? |
| end | | end |
| end | | end |
− | show = show .. " align" | + | if n > 1 then |
| + | spaced = string.rep( "_", n ) .. " " |
| + | end |
| + | show = show .. s |
| + | elseif Permit.builder.after == true then |
| + | spaced = "" |
| + | show = show .. " after" |
| elseif Permit.builder.dense == true then | | elseif Permit.builder.dense == true then |
| spaced = "" | | spaced = "" |
Zeile 1.179: |
Zeile 1.522: |
| show = show .. " dense" | | show = show .. " dense" |
| end | | end |
− | end
| + | if Permit.builder.last == true then |
− | if Permit.builder.last == true then
| + | suffix = spacer |
− | suffix = spacer
| + | show = show .. " last" |
− | show = show .. " last"
| + | end |
| end | | end |
| code = string.format( "N{{_N%s|%s_%s=%s_%s}}N", | | code = string.format( "N{{_N%s|%s_%s=%s_%s}}N", |
Zeile 1.190: |
Zeile 1.533: |
| spacer, | | spacer, |
| suffix ) | | suffix ) |
| + | if show == "block" then |
| + | show = "block newlines" |
| + | end |
| end | | end |
| if show then | | if show then |
Zeile 1.200: |
Zeile 1.546: |
| code = mw.text.nowiki( code ):gsub( "N", "\n" ) | | code = mw.text.nowiki( code ):gsub( "N", "\n" ) |
| code = mw.html.create( "code" ) | | code = mw.html.create( "code" ) |
| + | :css( "margin-left", "1em" ) |
| + | :css( "margin-right", "1em" ) |
| :wikitext( code ) | | :wikitext( code ) |
| if r then | | if r then |
Zeile 1.210: |
Zeile 1.558: |
| end | | end |
| end | | end |
− | Data.tree.format = source | + | if source then |
| + | Data.tag.format = source |
| + | end |
| return r | | return r |
| end -- format() | | end -- format() |
Zeile 1.220: |
Zeile 1.570: |
| -- Returns <div> | | -- Returns <div> |
| local r = mw.html.create( "div" ) | | local r = mw.html.create( "div" ) |
− | local s = feasible( Data.tree, true ) | + | local x = fashioned( Data.tree, true, r ) |
− | if s then | + | local s |
− | r:node( s ) | + | if x then |
| + | r = x |
| end | | end |
| if Data.leading then | | if Data.leading then |
| local toc = mw.html.create( "div" ) | | local toc = mw.html.create( "div" ) |
| + | local shift |
| if Config.suppressTOCnum then | | if Config.suppressTOCnum then |
| toc:addClass( Config.suppressTOCnum ) | | toc:addClass( Config.suppressTOCnum ) |
| + | if type( Config.stylesTOCnum ) == "string" then |
| + | local src = Config.stylesTOCnum .. "/styles.css" |
| + | s = TemplateData.frame:extensionTag( "templatestyles", |
| + | nil, |
| + | { src = src } ) |
| + | r:newline() |
| + | :node( s ) |
| + | end |
| end | | end |
| toc:css( "margin-top", "0.5em" ) | | toc:css( "margin-top", "0.5em" ) |
| :wikitext( "__TOC__" ) | | :wikitext( "__TOC__" ) |
| + | if Data.sibling then |
| + | local block = mw.html.create( "div" ) |
| + | if TemplateData.ltr then |
| + | shift = "right" |
| + | else |
| + | shift = "left" |
| + | end |
| + | block:css( "float", shift ) |
| + | :wikitext( Data.sibling ) |
| + | r:newline() |
| + | :node( block ) |
| + | :newline() |
| + | end |
| r:newline() | | r:newline() |
| :node( toc ) | | :node( toc ) |
| :newline() | | :newline() |
| + | if shift then |
| + | r:node( mw.html.create( "div" ) |
| + | :css( "clear", shift ) ) |
| + | :newline() |
| + | end |
| end | | end |
| s = features() | | s = features() |
| if s then | | if s then |
| if Data.leading then | | if Data.leading then |
− | r:node( mw.html.create( "h2" ) | + | r:node( mw.html.create( "h" .. Config.nested ) |
| :wikitext( factory( "doc-params" ) ) ) | | :wikitext( factory( "doc-params" ) ) ) |
| :newline() | | :newline() |
| end | | end |
| r:node( s ) | | r:node( s ) |
| + | end |
| + | if Data.shared then |
| + | local global = mw.html.create( "div" ) |
| + | :attr( "id", "templatedata-global" ) |
| + | local shift |
| + | if TemplateData.ltr then |
| + | shift = "right" |
| + | else |
| + | shift = "left" |
| + | end |
| + | global:css( "float", shift ) |
| + | :wikitext( string.format( "[[%s|%s]]", |
| + | Data.shared, "Global" ) ) |
| + | r:newline() |
| + | :node( global ) |
| end | | end |
| if Data.tree and Data.tree.format then | | if Data.tree and Data.tree.format then |
Zeile 1.264: |
Zeile 1.657: |
| local function free() | | local function free() |
| -- Remove JSON comment lines | | -- Remove JSON comment lines |
− | Data.source:gsub( "([{,\"'])(%s*\n%s*//.*\n%s*)([},\"'])", | + | if Data.source:find( "//", 1, true ) then |
− | "%1%3" )
| + | Data.source:gsub( "([{,\"'])(%s*\n%s*//.*\n%s*)([{},\"'])", |
| + | "%1%3" ) |
| + | end |
| end -- free() | | end -- free() |
| | | |
Zeile 1.296: |
Zeile 1.691: |
| div:wikitext( Data.strip ) | | div:wikitext( Data.strip ) |
| if Config.loudly then | | if Config.loudly then |
− | Data.div:node( mw.html.create( "hr" ) ) | + | Data.div:node( mw.html.create( "hr" ) |
| + | :css( { height = "7ex" } ) ) |
| else | | else |
| div:css( "display", "none" ) | | div:css( "display", "none" ) |
Zeile 1.302: |
Zeile 1.698: |
| Data.div:node( div ) | | Data.div:node( div ) |
| end | | end |
| + | end |
| + | if Data.lasting then |
| + | Fault( "deprecated type syntax" ) |
| + | end |
| + | if Data.less then |
| + | Fault( Config.solo ) |
| end | | end |
| end -- full() | | end -- full() |
Zeile 1.313: |
Zeile 1.715: |
| -- arglist -- table, template parameters | | -- arglist -- table, template parameters |
| -- Returns string | | -- Returns string |
− | --local spy=""
| |
| local source | | local source |
| favorize() | | favorize() |
Zeile 1.322: |
Zeile 1.723: |
| end | | end |
| end -- for k, v | | end -- for k, v |
| + | if arglist.heading and arglist.heading:match( "^[3-6]$" ) then |
| + | Config.nested = arglist.heading |
| + | else |
| + | Config.nested = "2" |
| + | end |
| Config.loudly = faculty( arglist.debug or adapt.debug ) | | Config.loudly = faculty( arglist.debug or adapt.debug ) |
− | --if mw.site.server:find( "//de.wikipedia.beta.wmflabs.org", 1, true ) then
| |
− | -- Config.loudly = true
| |
− | --end
| |
| Data.lazy = faculty( arglist.lazy ) and not Config.loudly | | Data.lazy = faculty( arglist.lazy ) and not Config.loudly |
| Data.leading = faculty( arglist.TOC ) | | Data.leading = faculty( arglist.TOC ) |
| + | if Data.leading and arglist.TOCsibling then |
| + | Data.sibling = mw.text.trim( arglist.TOCsibling ) |
| + | end |
| + | if arglist.lang then |
| + | Data.slang = arglist.lang:lower() |
| + | elseif adapt.lang then |
| + | Data.slang = adapt.lang:lower() |
| + | end |
| if arglist.JSON then | | if arglist.JSON then |
| source = arglist.JSON | | source = arglist.JSON |
| + | elseif arglist.Global then |
| + | source = TemplateData.getGlobalJSON( arglist.Global, |
| + | arglist.Local ) |
| elseif arglist[ 1 ] then | | elseif arglist[ 1 ] then |
| local s = mw.text.trim( arglist[ 1 ] ) | | local s = mw.text.trim( arglist[ 1 ] ) |
Zeile 1.341: |
Zeile 1.755: |
| Data.strip = s | | Data.strip = s |
| end | | end |
| + | end |
| + | if type( arglist.vertical ) == "string" and |
| + | arglist.vertical:match( "^%d*%.?%d+[emprx]+$" ) then |
| + | Data.scroll = arglist.vertical |
| end | | end |
| if not source then | | if not source then |
Zeile 1.346: |
Zeile 1.764: |
| source = find() | | source = find() |
| if not source and | | if not source and |
− | Config.subpage and Config.suffix and
| |
| not Data.title.text:match( Config.subpage ) then | | not Data.title.text:match( Config.subpage ) then |
| local s = string.format( Config.suffix, | | local s = string.format( Config.suffix, |
Zeile 1.355: |
Zeile 1.772: |
| end | | end |
| end | | end |
− | --if source and
| |
− | -- ( source:find( "|", 1, true ) or
| |
− | -- source:find( "}}", 1, true ) ) then
| |
− | -- -- <ref
| |
− | --spy=string.format( "[[category:%s]]", Config.strange )
| |
− | --end
| |
| end | | end |
− | if not Data.lazy and Config.subpage then | + | if not Data.lazy then |
| if not Data.title then | | if not Data.title then |
| Data.title = mw.title.getCurrentTitle() | | Data.title = mw.title.getCurrentTitle() |
Zeile 1.368: |
Zeile 1.779: |
| Data.lazy = Data.title.text:match( Config.subpage ) | | Data.lazy = Data.title.text:match( Config.subpage ) |
| end | | end |
− | TemplateData.getPlainJSON( source ) | + | if type( source ) == "string" then |
− | return finalize() | + | TemplateData.getPlainJSON( source ) |
− | --return spy .. finalize()
| + | end |
| + | return finalize( faculty( arglist.source ) ) |
| end -- furnish() | | end -- furnish() |
| | | |
| | | |
| | | |
− | TemplateData.failsafe = function ( assert )
| + | Failsafe.failsafe = function ( atleast ) |
| -- Retrieve versioning and check for compliance | | -- Retrieve versioning and check for compliance |
| -- Precondition: | | -- Precondition: |
− | -- assert -- string, with required version or "wikidata", | + | -- atleast -- string, with required version |
− | -- or false | + | -- or wikidata|item|~|@ or false |
| -- Postcondition: | | -- Postcondition: |
− | -- Returns string with appropriate version, or false | + | -- Returns string -- with queried version/item, also if problem |
− | local since = assert | + | -- false -- if appropriate |
| + | -- 2020-08-17 |
| + | local since = atleast |
| + | local last = ( since == "~" ) |
| + | local linked = ( since == "@" ) |
| + | local link = ( since == "item" ) |
| local r | | local r |
− | if since == "wikidata" then | + | if last or link or linked or since == "wikidata" then |
− | local item = TemplateData.item | + | local item = Failsafe.item |
| since = false | | since = false |
| if type( item ) == "number" and item > 0 then | | if type( item ) == "number" and item > 0 then |
− | local entity = mw.wikibase.getEntity( string.format( "Q%d", | + | local suited = string.format( "Q%d", item ) |
− | item ) )
| + | if link then |
− | if type( entity ) == "table" then
| + | r = suited |
− | local vsn = entity:formatPropertyValues( "P348" )
| + | else |
− | if type( vsn ) == "table" and
| + | local entity = mw.wikibase.getEntity( suited ) |
− | type( vsn.value) == "string" and
| + | if type( entity ) == "table" then |
− | vsn.value ~= "" then
| + | local seek = Failsafe.serialProperty or "P348" |
− | r = vsn.value
| + | 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 |
| + | elseif linked then |
| + | if mw.title.getCurrentTitle().prefixedText |
| + | == mw.wikibase.getSitelink( suited ) then |
| + | r = false |
| + | else |
| + | r = suited |
| + | end |
| + | else |
| + | r = vsn.value |
| + | end |
| + | end |
| end | | end |
| end | | end |
| end | | end |
| end | | end |
− | if not r then | + | if type( r ) == "nil" then |
− | if not since or since <= TemplateData.serial then | + | if not since or since <= Failsafe.serial then |
− | r = TemplateData.serial | + | r = Failsafe.serial |
| else | | else |
| r = false | | r = false |
Zeile 1.408: |
Zeile 1.841: |
| end | | end |
| return r | | return r |
− | end -- TemplateData.failsafe() | + | end -- Failsafe.failsafe() |
| + | |
| + | |
| + | |
| + | |
| + | TemplateData.getGlobalJSON = function ( access, adapt ) |
| + | -- Retrieve TemplateData from a global repository (JSON) |
| + | -- Parameter: |
| + | -- access -- string, with page specifier (on WikiMedia Commons) |
| + | -- adapt -- JSON string or table with local overrides |
| + | -- Returns true, if succeeded |
| + | local plugin = Fetch( "/global" ) |
| + | local r |
| + | if type( plugin ) == "table" and |
| + | type( plugin.fetch ) == "function" then |
| + | local s, got = plugin.fetch( access, adapt ) |
| + | if got then |
| + | Data.got = got |
| + | Data.order = got.paramOrder |
| + | Data.shared = s |
| + | r = true |
| + | full() |
| + | else |
| + | Fault( s ) |
| + | end |
| + | end |
| + | return r |
| + | end -- TemplateData.getGlobalJSON() |
| | | |
| | | |
Zeile 1.418: |
Zeile 1.878: |
| -- Returns string, or not | | -- Returns string, or not |
| if type( adapt ) == "string" then | | if type( adapt ) == "string" then |
| + | local JSONutil = Fetch( "JSONutil", true ) |
| Data.source = adapt | | Data.source = adapt |
| free() | | free() |
− | Data.got = mw.text.jsonDecode( Data.source ) | + | if JSONutil then |
− | if Data.got then | + | local Multilingual = Fetch( "Multilingual", true ) |
| + | local f |
| + | if Multilingual then |
| + | f = Multilingual.i18n |
| + | end |
| + | Data.got = JSONutil.fetch( Data.source, true, f ) |
| + | else |
| + | local lucky |
| + | lucky, Data.got = pcall( mw.text.jsonDecode, Data.source ) |
| + | end |
| + | if type( Data.got ) == "table" then |
| full() | | full() |
− | if Data.lasting then
| + | elseif not Data.strip then |
− | Fault( "deprecated type syntax" )
| + | local scream = type( Data.got ) |
− | end | + | if scream == "string" then |
− | if Data.less then
| + | scream = Data.got |
− | Fault( Config.solo ) | + | else |
| + | scream = "Data.got: " .. scream |
| end | | end |
− | elseif not Data.strip then
| + | Fault( "fatal JSON error: " .. scream ) |
− | Fault( "fatal JSON error" ) | |
| end | | end |
| end | | end |
Zeile 1.458: |
Zeile 1.929: |
| end | | end |
| return r | | return r |
− | end -- p.f() | + | end -- p.f |
| | | |
| p.failsafe = function ( frame ) | | p.failsafe = function ( frame ) |
Zeile 1.475: |
Zeile 1.946: |
| end | | end |
| end | | end |
− | return TemplateData.failsafe( since ) or "" | + | return Failsafe.failsafe( since ) or "" |
− | end -- p.failsafe() | + | end -- p.failsafe |
| | | |
| p.TemplateData = function () | | p.TemplateData = function () |