Modul:Vorlage:LuaModuleDoc: Unterschied zwischen den Versionen

Aus ÖsterreichWiki
Zur Navigation springen Zur Suche springen
wp>PerfektesChaos
(2016-11-26)
K (4 Versionen importiert)
 
(11 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
local Serial = "2016-11-26"
local LuaModuleDoc = { suite  = "LuaModuleDoc",
                      serial = "2019-10-30",
                      item  = 12981914,
                      frame  = false,
                      ns    = -9999,
                                -- current namespace number
                      nsDocs = -99999,
                                -- central documentation namespace number
                      title  = false,
                                -- current page Title object
                      transl = false }
--[=[
--[=[
Support {{LuaModuleDoc}}
Support {{LuaModuleDoc}}
* nav()
* nav()
* failsafe()
* failsafe()
require: LuaWiki
]=]
]=]
local Failsafe = LuaModuleDoc






-- Module globals
local function fetch( arg, assign )
local Lucky, LuaWiki = pcall( require, "Module:LuaWiki" )
    -- Retrieve template argument
local CurrentTitle
    -- Precondition:
local Frame
    --    arg    -- string or number; argument identifier
    --    assign  -- any, optional; default value
    -- Uses:
    --     >  LuaModuleDoc.frame
    local r = LuaModuleDoc.frame.args[ arg ]
    if type( r ) ~= "string" then
        if assign == nil then
            r = "{{{<" .. arg .. ">}}}"
        else
            r = assign
        end
    end
    return r
end -- fetch()




Zeile 23: Zeile 46:
     -- Uses:
     -- Uses:
     --    mw.title.makeTitle()
     --    mw.title.makeTitle()
     local s = LuaWiki.getArg( slot, "" )
     local s = fetch( slot, "" )
     local r
     local r
     if #s > 0 then
     if #s > 0 then
Zeile 33: Zeile 56:
     return r
     return r
end -- catIfDefined()
end -- catIfDefined()
local function createPage( swift, sub, start, ns, script )
    -- Create button for page creation
    --    swift  -- string;
    --                "NoPageCentral", "NoTalkCentral", "NoTalkRedir"
    --    sub    -- string; page name to be created
    --    start  -- string; defined pageDocRoot argument
    --    ns      -- number; namespace
    --    script  -- string; module name (main)
    -- Return:
    --    string
    -- Uses:
    --    >  LuaModuleDoc.frame
    --    fetch()
    -- MediaWiki:Move-leave-redirect  Weiterleitung erstellen
    -- MediaWiki:autosumm-new          Seite wurde neu angelegt: „$1“
    local setup = "preload" .. swift:sub( 7 )
    local r
    setup = fetch( setup )
    if setup then
        local create = { action  = "edit",
                        preload = setup,
                        redlink = "1" }
        local button, path, show, story, summary
        if swift == "NoTalkRedir" then
            show    = "move-leave-redirect"
            story  = string.format( "%s/%s", start, script )
            story  = mw.title.makeTitle( ns, story ).prefixedText
            story  = string.format( "[[%s]]", story )
            summary = "#redirect " .. story
        else
            local s = fetch( "langsRequest", false )
            show    = "recreate"
            if s then
                s = mw.text.trim( s )
                if s ~= "" then
                    s = "|" .. s
                end
            end
            story = ( s or "" )
            summary = "{{LuaModuleDoc}}"
        end
    --  summary = mw.message.new( "autosumm-new" ):params( summary )
        create.summary      = summary
        create.preloadtitle = summary
        if story then
            create[ "preloadparams[]" ] = story
        end
        path  = { sub,  mw.uri.buildQueryString( create ) }
        r      = LuaModuleDoc.frame:callParserFunction( "fullurl", path )
        show  = mw.message.new( show ):plain()
        button = mw.title.makeTitle( mw.site.namespaces.Template.id,
                                    "MediaWiki-Button" )
        if button.exists then
            button = { template = button.text,
                      Typ      = "progressive",
                      ["Groß"] = "1",
                      Link    = r,
                      Text    = show }
            r      = LuaModuleDoc.frame:expandTemplate{
                                                title = button.template,
                                                args  = button }
        else
            r = string.format( "<br>[%s '''%s''']", r, show )
        end
    end
    return r or ""
end -- createPage()




Zeile 40: Zeile 133:
     --    script  -- string; module name (main)
     --    script  -- string; module name (main)
     -- Uses:
     -- Uses:
     --    LuaWiki.getArg()
     --    >  LuaModuleDoc.title
     --    >< CurrentTitle
    --    >  LuaModuleDoc.frame
    --    fetch()
     --    mw.wikibase.getEntity()
    --    mw.title.makeTitle()
     -- Return:
     -- Return:
     --    string
     --    string
    -- Uses:
    --    mw.wikibase.getEntity()
    --    mw.title.makeTitle()
     local entity = mw.wikibase.getEntity()
     local entity = mw.wikibase.getEntity()
     local r
     local r
     if entity then
     if type( entity ) == "table" then
         local mode = 0
         local mode = 0
         local repo = entity:formatPropertyValues( "P1324" )
         local repo = entity:formatPropertyValues( "P1324" )
         local params, s, t
         local params, s
         if repo  and repo.value  and repo.value:find( "//" ) then
         if type( repo ) == "table" and
             repo = mw.uri.new( repo.value )
          type( repo.value) == "string" and
             if repo  and repo.path:match( "^/wiki/" ) then
          repo.value:find( "//" ) then
            local t = mw.text.split( repo.value, ",%s+" )
            if #t > 1 then
                for i = 1, #t do
                    if t[ i ]:find( mw.site.server, 1, true ) then
                        s = t[ i ]
                        break -- for i
                    end
                end -- for i
                if not s then
                    s = t[ 1 ]
                end
            else
                s = repo.value
            end
             repo = mw.uri.new( s )
             if type( repo.path ) == "string" and
              repo.path:match( "^/wiki/" ) then
                 local space
                 local space
                 space, s = mw.ustring.match( repo.path:sub( 7 ),
                 space, s = repo.path:sub( 7 ):match( "^([^:]+):(.+)$" )
                                            "^([^:]+):(.+)$" )
                 if space and s then
                 if space and s then
                     t = mw.title.makeTitle( space, s )
                     t = mw.title.makeTitle( space, s )
                     s = "//" .. repo.host
                     s = "//" .. repo.host
                     if mw.title.equals( CurrentTitle, t )  and
                     if mw.title.equals( LuaModuleDoc.title, t )  and
                       mw.site.server:find( s, 1, true ) then
                       mw.site.server:find( s, 1, true ) then
                         mode = 2
                         mode = 2
Zeile 70: Zeile 179:
                 end
                 end
             end
             end
             s = LuaWiki.getArg( "templateGlobal", "" )
             s = fetch( "templateGlobal", "" )
             if #s > 0 then
             if #s > 0 then
                 local lucky, code = pcall( require,
                 local l, bib = pcall( require,
                                          CurrentTitle.prefixedText )
                                      LuaModuleDoc.title.prefixedText )
                 local vsn = entity:formatPropertyValues( "P348" )
                 local vsn = entity:formatPropertyValues( "P348" )
                 params = { }
                 params = { }
Zeile 81: Zeile 190:
                                                 repo.host )
                                                 repo.host )
                 end
                 end
                 if vsn  and vsn.value and vsn.value ~= "" then
                 if type( vsn ) == "table" and
                  type( vsn.value) == "string" and
                  vsn.value ~= "" then
                     params.version = vsn.value
                     params.version = vsn.value
                 end
                 end
                 if type( code ) == "table" and  code.failsafe then
                 if type( bib ) == "table" then
                    t = type( code.failsafe )
                    local serial
                    if t == "function" then
                    if bib.failsafe then
                        code = code.failsafe( { args = { } } )
                        if type( bib.failsafe ) == "function" then
                         t    = type( code )
                            serial = bib.failsafe( { args = { } } )
                     else
                         else
                         code = code.failsafe
                            serial = bib.failsafe
                        end
                     elseif bib[ "#serial"] then
                         serial = bib[ "#serial"]
                     end
                     end
                     if t == "number" then
                     if type( serial ) == "number" then
                         code = string.format( "%d", code )
                         serial = string.format( "%d", serial )
                        t    = "string"
                     end
                     end
                     if t == "string" then
                     if type( serial ) == "string" then
                         params.here = code
                         params.here = serial
                     end
                     end
                 end
                 end
                 if params.version  and  params.here  and
                 if fetch( "forkedGlobal", "0" ) ~= "1"  and
                  params.version  and  params.here  and
                   params.version ~= params.here  then
                   params.version ~= params.here  then
                     params.update = "1"
                     params.update = "1"
                 end
                 end
                 r = Frame:expandTemplate{ title=s,
                 r = LuaModuleDoc.frame:expandTemplate{ title=s,
                                          args=params }
                                                      args=params }
             end
             end
         end
         end
         s = LuaWiki.getArg( "categoryWikiData", "" )
         s = fetch( "categoryWikiData", "" )
         if #s > 0 then
         if #s > 0 then
             local slot
             local slot
Zeile 141: Zeile 255:




local function navDevelop( nsDocs, start, script )
local function navDevelop( start, script )
     -- Most interesting test and development page
     -- Most interesting test and development page
     -- Precondition:
     -- Precondition:
    --    nsDocs  -- number; central documentation namespace number
     --    start  -- string; central documentation root
     --    start  -- string; central documentation root
     --    script  -- string; basic module name
     --    script  -- string; basic module name
Zeile 150: Zeile 263:
     --    string or false:  full page name, if any
     --    string or false:  full page name, if any
     -- Uses:
     -- Uses:
    --    >  LuaModuleDoc.nsDocs
     --    mw.title.makeTitle()
     --    mw.title.makeTitle()
     local n  = nsDocs
     local n  = LuaModuleDoc.nsDocs
     local r  = false
     local r  = false
     local sub = "/" .. LuaWiki.getArg( "subTest", "Test" )
     local sub = "/" .. fetch( "subTest", "Test" )
     local s  = string.format( "%s/%s%s", start, script, sub )
     local s  = string.format( "%s/%s%s", start, script, sub )
     local t  = mw.title.makeTitle( n, s )
     local t  = mw.title.makeTitle( n, s )
Zeile 176: Zeile 290:
     end
     end
     if t then
     if t then
         r = mw.site.namespaces[ n ].name .. ":" .. s
         r = string.format( "%s:%s",
                          mw.site.namespaces[ n ].name, s )
     end
     end
     return r
     return r
Zeile 189: Zeile 304:
     --    specific  -- string, optional; additional information
     --    specific  -- string, optional; additional information
     -- Uses:
     -- Uses:
     --    LuaWiki.getArg()
     --    >  LuaModuleDoc.frame
    --    LuaWiki.transclude()
     --    fetch()
     --    LuaWiki.error()
     local show = fetch( "pageErr" )
     local show = LuaWiki.getArg( "pageErr" )
     local r
     local r
     if type( show ) == "string" then
     if type( show ) == "string" then
Zeile 199: Zeile 313:
             table.insert( pars, specific )
             table.insert( pars, specific )
         end
         end
         r = LuaWiki.transclude( show, pars )
         r = LuaModuleDoc.frame:expandTemplate{ title = show,
                                              args = pars }
     else
     else
         r = LuaWiki.error( "arg 'pageErr' missing" )
         local e = mw.html.create( "span" )
                        :attr( "class", "error" )
                        :wikitext( error( "arg 'pageErr' missing", 3 ) )
        r = tostring( e )
     end
     end
     return r
     return r
Zeile 242: Zeile 360:




local function navLangs( nsDocs, start, script )
local function navLangs( start, script )
     -- Analyze languages
     -- Analyze languages
     -- Precondition:
     -- Precondition:
     --    current page is supposed to transclude LuaModuleDoc
     --    current page is supposed to transclude LuaModuleDoc
    --    nsDocs  -- number; central documentation namespace number
     --    start  -- string; central documentation root
     --    start  -- string; central documentation root
     --    script  -- string; basic module name
     --    script  -- string; basic module name
     -- Return:
     -- Postcondition:
     --    table: args for navigation template
     --    LuaModuleDoc.transl is set up as table:
     --             [1] basic module name
    --                        args for navigation template
     --             [2] number of language codes  +  1
     --                         [1] basic module name
     --             [3] first language code
     --                         [2] number of language codes  +  1
     --             [4] second language code
     --                         [3] first language code
     --             ... list of further language codes
     --                         [4] second language code
     --                         ... list of further language codes
     -- Uses:
     -- Uses:
     --    LuaWiki.getArg()
     --    >  LuaModuleDoc.nsDocs
    --      < LuaModuleDoc.transl
    --    fetch()
     --    navLang()
     --    navLang()
     --    mw.title.makeTitle()
     --    mw.title.makeTitle()
     local e, i, s, t
     local e, i, s, t
    local r = { }
     local specified = fetch( "langsRequest", false )
     local specified = LuaWiki.getArg( "langsRequest", false )
     local super    = start .. "/" .. script .. "/"
     local super    = start .. "/" .. script .. "/"
    LuaModuleDoc.transl = { }
     if type( specified ) == "string" then
     if type( specified ) == "string" then
         if specified:match( "^%s*$" ) then
         if specified:match( "^%s*$" ) then
Zeile 269: Zeile 389:
         end
         end
     end
     end
     navLang( LuaWiki.getArg( "langsDefault" ),  r,  specified )
     navLang( fetch( "langsDefault" ),  LuaModuleDoc.transl,  specified )
     navLang( LuaWiki.getArg( "langsMore" ),  r,  true  )
     navLang( fetch( "langsMore" ),  LuaModuleDoc.transl,  true  )
     navLang( specified, r, false )
     navLang( specified, LuaModuleDoc.transl, false )
     if #r < 1 then
     if #LuaModuleDoc.transl < 1 then
         r = { { "en", false } }
         LuaModuleDoc.transl = { { "en", false } }
     end
     end
     for i = #r, 1, -1 do
     for i = #LuaModuleDoc.transl, 1, -1 do
         e = r[ i ]
         e = LuaModuleDoc.transl[ i ]
         s = e[ 1 ]
         s = e[ 1 ]
         if e[ 2 ] then
         if e[ 2 ] then
             t = mw.title.makeTitle( nsDocs,  super .. s )
             t = mw.title.makeTitle( LuaModuleDoc.nsDocs,  super .. s )
             if not t.exists then
             if not t.exists then
                 s = false
                 s = false
Zeile 285: Zeile 405:
         end
         end
         if s then
         if s then
             r[ i ] = s
             LuaModuleDoc.transl[ i ] = s
         else
         else
             table.remove( r, i )
             table.remove( LuaModuleDoc.transl, i )
         end
         end
     end -- for i -1
     end -- for i -1
     table.insert( r, 1, script )
     table.insert( LuaModuleDoc.transl,
     table.insert( r, 2, tostring( #r ) )
                  1,
    return r
                  script )
     table.insert( LuaModuleDoc.transl,
                  2,
                  tostring( #LuaModuleDoc.transl ) )
end -- navLangs()
end -- navLangs()






local function navMerge( start, swift, ns, nsDocs, script, sub, lead )
local function navMerge( start, swift, script, sub, lead )
     -- Include various external content into page
     -- Include various external content into page
     -- Precondition:
     -- Precondition:
     --    start  -- string; defined pageDocRoot argument
     --    start  -- string; defined pageDocRoot argument
     --    swift  -- string; defined pageNav argument
     --    swift  -- string; defined pageNav argument
    --    ns      -- number; current namespace number
    --    nsDocs  -- number; central documentation namespace number
     --    script  -- string; module name (main)
     --    script  -- string; module name (main)
     --    sub    -- string or false; possible sub-module name
     --    sub    -- string or false; possible sub-module name
     --    lead    -- true: Module: namespace;  false: text namespace
     --    lead    -- true: Module: namespace;  false: text namespace
     -- Uses:
     -- Uses:
     --    >< CurrentTitle
     --    > LuaModuleDoc.transl
     --    navLangs()
    --    >  LuaModuleDoc.ns
     --    LuaWiki.transclude()
     --    >  LuaModuleDoc.nsDocs
    --    >  LuaModuleDoc.title
     --    >  LuaModuleDoc.frame
     --    navError()
     --    navError()
     --    mw.title.makeTitle()
     --    mw.title.makeTitle()
     --    LuaWiki.getArg()
     --    createPage()
     --    LuaWiki.isExisting()
     --    fetch()
     local super  = false
     local server = mw.site.server
     local collect = navLangs( nsDocs, start, script )
     local super  = false
     local t       = navDevelop( nsDocs, start, script )
     local t     = navDevelop( start, script )
     local r
     local collect, low, r, s
     local s
     collect = LuaModuleDoc.transl
     if t then
     if t then
         collect.Test = t
         collect.Test = t
     end
     end
     if ns == nsDocs then
     if LuaModuleDoc.ns == LuaModuleDoc.nsDocs then
         s = string.format( "%s/%s", start, script )
         s = string.format( "%s/%s", start, script )
         if CurrentTitle.text == s then
         if LuaModuleDoc.title.text == s then
             super = CurrentTitle.text .. "/"
             super = LuaModuleDoc.title.text .. "/"
         elseif sub then
         elseif sub then
             collect.subDoc = sub
             collect.subDoc = sub
             collect.subModule = sub
             collect.subModule = sub
             s = string.format( "%s/%s/%s", start, script, sub )
             s = string.format( "%s/%s/%s", start, script, sub )
             if CurrentTitle.text == s then
             if LuaModuleDoc.title.text == s then
                 s = string.format( "%s/%s", s, collect[ 3 ] )
                 s = string.format( "%s/%s", s, collect[ 3 ] )
                 t = mw.title.makeTitle( nsDocs, s )
                 t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
                 if t.exists then
                 if t.exists then
                     super = CurrentTitle.text .. "/"
                     super = LuaModuleDoc.title.text .. "/"
                 end
                 end
             end
             end
Zeile 341: Zeile 464:
     elseif lead and sub then
     elseif lead and sub then
         s = string.format( "%s/%s/%s", start, script, sub )
         s = string.format( "%s/%s/%s", start, script, sub )
         t = mw.title.makeTitle( nsDocs, s )
         t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
         if t.exists then
         if t.exists then
             collect.subDoc = sub
             collect.subDoc = sub
         end
         end
     end
     end
     r = LuaWiki.transclude( swift, collect )
     if server:match( "%.beta%.wmflabs%.org$" ) then
    t = CurrentTitle.talkPageTitle
        local slang, series = server:match( "//(%l+)%.(%l+)%." )
    if t then
        low = true
        s = t.exists
        if series == "wikipedia" then
    else
            if slang == "de" then
         s = false
                collect.BETA = "w:de:"  --Talk
            end
         end
     end
     end
     if not s then
    r = LuaModuleDoc.frame:expandTemplate{ title = swift,
         if super then
                                          args = collect }
             s = "NoTalkCentral"
     if not low then
        elseif ns == nsDocs + 1 then
        t = LuaModuleDoc.title.talkPageTitle
            s = false
         if LuaModuleDoc.ns == mw.site.namespaces.Module.id then
        else
            local doc
             s = "NoTalkRedir"
             s   = string.format( "%s/%s", start, script )
            doc = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
            if not doc.exists then
                r = r .. createPage( "NoPageCentral",
                                    doc.prefixedText,
                                    start,
                                    LuaModuleDoc.nsDocs,
                                    script )
                t = false
             end
         end
         end
         if s then
         if t  and  not t.exists then
             r = r .. navError( s )
            if super then
                s = "NoTalkCentral"
            elseif LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
                s = false
            else
                s = "NoTalkRedir"
            end
             if s then
                r = string.format( "%s%s%s",
                                  r,
                                  navError( s ),
                                  createPage( s,
                                              t.prefixedText,
                                              start,
                                              LuaModuleDoc.nsDocs + 1,
                                              script ) )
            end
         end
         end
     end
     end
Zeile 369: Zeile 519:
         local p1 = "^%s*" .. d .. "<onlyinclude>"
         local p1 = "^%s*" .. d .. "<onlyinclude>"
         local p2 = "%s*<noinclude>" .. d .. "</noinclude>"
         local p2 = "%s*<noinclude>" .. d .. "</noinclude>"
        local space, sub, support
         for i = 3, #collect do
         for i = 3, #collect do
             t = mw.title.makeTitle( nsDocs, super .. collect[ i ] )
             t = mw.title.makeTitle( LuaModuleDoc.nsDocs,
                                    super .. collect[ i ] )
             s = t:getContent()
             s = t:getContent()
             if s then
             if s then
Zeile 380: Zeile 532:
                                                 t.prefixedText ) )
                                                 t.prefixedText ) )
                 else
                 else
                     r = r .. LuaWiki.transclude( t.prefixedText )
                     r = r ..
                        LuaModuleDoc.frame:expandTemplate{
                                                title = t.prefixedText }
                     break    -- for i
                     break    -- for i
                 end
                 end
             end
             end
         end -- for i
         end -- for i
         s = LuaWiki.getArg( "pageTemplateInsert", "" )
         s = fetch( "pageTemplateInsert", "" )
         if LuaWiki.isExisting( s ) then
        space, support = s:match( "^([^:]+):(.+)$" )
             local suppress = LuaWiki.getArg( "noHint", "" )
         if space  and  mw.title.makeTitle( space, support ).exists then
             local suppress = fetch( "noHint", "" )
             if #suppress == 0 then
             if #suppress == 0 then
                 local swift = collect[ 1 ]
                 local swift = collect[ 1 ]
Zeile 393: Zeile 548:
                     swift = string.format( "%s/%s", swift, sub )
                     swift = string.format( "%s/%s", swift, sub )
                 end
                 end
                 r = r .. LuaWiki.transclude( s, { swift } )
                 r = r ..
                    LuaModuleDoc.frame:expandTemplate{ title = s,
                                                      args = { swift } }
             end
             end
         end
         end
         s = LuaWiki.getArg( "categoryDocs", "" )
         s = fetch( "categoryDocs", "" )
         if #s > 0 then
         if #s > 0 then
             i = mw.title.makeTitle( "Category", s )
             i = mw.title.makeTitle( "Category", s )
Zeile 414: Zeile 571:




local function navPage( lead, ns, nsDocs )
local function navPage( lead )
     -- Return navigation text; analyze page location
     -- Return navigation text; analyze page location
     -- Precondition:
     -- Precondition:
     --    current namespace will support LuaModuleDoc
     --    current namespace will support LuaModuleDoc
     --    lead    -- true: Module: namespace;  false: text namespace
     --    lead    -- true: Module: namespace;  false: text namespace
    --    ns      -- number; current namespace
    --    nsDocs  -- number; namespace for doc
     -- Uses:
     -- Uses:
     --    >< CurrentTitle
     --    > LuaModuleDoc.title
     --    LuaWiki.getArg()
     --    >  LuaModuleDoc.transl
    --    fetch()
    --    navLangs()
    --    navMerge()
     --    navError()
     --    navError()
    --    navMerge()
     local r
     local r
     local start = LuaWiki.getArg( "pageDocRoot" )
     local start = fetch( "pageDocRoot" )
     if type( start ) == "string" then
     if type( start ) == "string" then
         local s      = "^"
         local s      = "^"
Zeile 435: Zeile 592:
         end
         end
         s = s .. "([^/]+)/(.*/?)$"
         s = s .. "([^/]+)/(.*/?)$"
         script, s = mw.ustring.match( CurrentTitle.text .. "/",  s )
         script, s = string.match( LuaModuleDoc.title.text .. "/",  s )
         if type( script ) == "string" then
         if type( script ) == "string" then
             local sub  = false
             local sub  = false
             local swift = LuaWiki.getArg( "pageNav" )
             local swift = fetch( "pageNav" )
            navLangs( start, script )
             if type( s ) == "string" then
             if type( s ) == "string" then
                 if #s > 1 then
                 if #s > 1 then
Zeile 447: Zeile 605:
                     if q.exists and q.contentModel == "Scribunto" then
                     if q.exists and q.contentModel == "Scribunto" then
                         sub = s
                         sub = s
                        for i = 1, #LuaModuleDoc.transl do
                            if LuaModuleDoc.transl[ i ] == s then
                                sub = false
                                break    -- for i
                            end
                        end -- for i
                     end
                     end
                 end
                 end
             end
             end
             if type( swift ) == "string" then
             if type( swift ) == "string" then
                 r = navMerge( start, swift, ns, nsDocs, script, sub, lead )
                 r = navMerge( start,
                              swift,
                              script,
                              sub,
                              lead )
             else
             else
                 r = navError( "configMissing", "pageNav" )
                 r = navError( "configMissing", "pageNav" )
             end
             end
         else
         else
             r = navError( "BadPage" ) .. CurrentTitle.text
             r = navError( "BadPage" ) .. LuaModuleDoc.title.text
         end
         end
     else
     else
Zeile 469: Zeile 637:
     -- Start execution; return navigation text; analyze namespace
     -- Start execution; return navigation text; analyze namespace
     -- Uses:
     -- Uses:
     --    >< CurrentTitle
     --     < LuaModuleDoc.title
     --    LuaWiki.getArg()
     --      < LuaModuleDoc.ns
    --      < LuaModuleDoc.nsDocs
     --    fetch()
     --    mw.title.getCurrentTitle()
     --    mw.title.getCurrentTitle()
     --    navPage()
     --    navPage()
     --    navError()
     --    navError()
     local r
     local r
     local nsDocs = LuaWiki.getArg( "nsDocs" )
     local nsDocs = fetch( "nsDocs" )
     if nsDocs then
     if nsDocs then
         CurrentTitle = mw.title.getCurrentTitle()
         local lead
         local ns   = CurrentTitle.namespace
        LuaModuleDoc.title  = mw.title.getCurrentTitle()
         local lead = ( ns == mw.site.namespaces.Module.id )
         LuaModuleDoc.ns     = LuaModuleDoc.title.namespace
         nsDocs = tonumber( nsDocs )
         lead               = ( LuaModuleDoc.ns ==
         if lead or ns == nsDocs  or ns == nsDocs + 1 then
                                mw.site.namespaces.Module.id )
             r = navPage( lead, ns, nsDocs )
         LuaModuleDoc.nsDocs = tonumber( nsDocs )
         if lead or
          LuaModuleDoc.ns == LuaModuleDoc.nsDocs  or
          LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
             r = navPage( lead )
         else
         else
             r = navError( "BadNamespace" )
             r = navError( "BadNamespace" )
Zeile 491: Zeile 665:
     return  r
     return  r
end -- navigation()
end -- navigation()
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()






-- Provide template access
-- Provide template access
local p = {}
local p = {}


function p.nav( frame )
function p.nav( frame )
     -- Uses:
     -- Uses:
     --     >  LuaWiki
     --     < LuaModuleDoc.frame
     --    navigation()
     --    navigation()
     local r
     local lucky, r
     if type( LuaWiki ) == "table" then
     LuaModuleDoc.frame = frame
        Frame = frame
    lucky, r = pcall( navigation )
        Lucky, r = pcall( navigation )
     if not lucky then
        r = r or ""
         local e = mw.html.create( "span" )
     else
                        :attr( "class", "error" )
         r = string.format( "<span class=\"error\">%s</span>", LuaWiki )
                        :wikitext( r )
        r = tostring( e )
     end
     end
     return r
     return r or ""
end
end


function p.failsafe()
 
     return Serial
 
p.failsafe = function ( frame )
    -- Check or retrieve version information
    -- Precondition:
    --    frame  -- object; #invoke environment
    -- Postcondition:
    --    Return string with error message or ""
    -- Uses:
    --    LuaModuleDoc.failsafe()
    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()
end -- p.failsafe()


return p
return p

Aktuelle Version vom 4. Juli 2020, 20:54 Uhr

Modul:Vorlage:LuaModuleDoc:142: attempt to index field 'wikibase' (a nil value)


local LuaModuleDoc = { suite  = "LuaModuleDoc",
                       serial = "2019-10-30",
                       item   = 12981914,
                       frame  = false,
                       ns     = -9999,
                                -- current namespace number
                       nsDocs = -99999,
                                -- central documentation namespace number
                       title  = false,
                                -- current page Title object
                       transl = false }
--[=[
Support {{LuaModuleDoc}}
* nav()
* failsafe()
]=]
local Failsafe = LuaModuleDoc



local function fetch( arg, assign )
    -- Retrieve template argument
    -- Precondition:
    --     arg     -- string or number; argument identifier
    --     assign  -- any, optional; default value
    -- Uses:
    --     >  LuaModuleDoc.frame
    local r = LuaModuleDoc.frame.args[ arg ]
    if type( r ) ~= "string" then
        if assign == nil then
            r = "{{{<" .. arg .. ">}}}"
        else
            r = assign
        end
    end
    return r
end -- fetch()



local function catIfDefined( slot )
    -- Categorize if category defined
    --     slot  -- string; Config entry
    -- Return:
    --     string or false:  categorization, if any
    -- Uses:
    --     mw.title.makeTitle()
    local s = fetch( slot, "" )
    local r
    if #s > 0 then
        local t = mw.title.makeTitle( "Category", s )
        if t.exists then
            r = string.format( "[[%s]]", t.prefixedText )
        end
    end
    return r
end -- catIfDefined()



local function createPage( swift, sub, start, ns, script )
    -- Create button for page creation
    --     swift   -- string;
    --                "NoPageCentral", "NoTalkCentral", "NoTalkRedir"
    --     sub     -- string; page name to be created
    --     start   -- string; defined pageDocRoot argument
    --     ns      -- number; namespace
    --     script  -- string; module name (main)
    -- Return:
    --     string
    -- Uses:
    --     >  LuaModuleDoc.frame
    --     fetch()
    -- MediaWiki:Move-leave-redirect   Weiterleitung erstellen
    -- MediaWiki:autosumm-new          Seite wurde neu angelegt: „$1“
    local setup = "preload" .. swift:sub( 7 )
    local r
    setup = fetch( setup )
    if setup then
        local create = { action  = "edit",
                         preload = setup,
                         redlink = "1" }
        local button, path, show, story, summary
        if swift == "NoTalkRedir" then
            show    = "move-leave-redirect"
            story   = string.format( "%s/%s", start, script )
            story   = mw.title.makeTitle( ns, story ).prefixedText
            story   = string.format( "[[%s]]", story )
            summary = "#redirect " .. story
        else
            local s = fetch( "langsRequest", false )
            show    = "recreate"
            if s then
                s = mw.text.trim( s )
                if s ~= "" then
                    s = "|" .. s
                end
            end
            story = ( s or "" )
            summary = "{{LuaModuleDoc}}"
        end
    --  summary = mw.message.new( "autosumm-new" ):params( summary )
        create.summary      = summary
        create.preloadtitle = summary
        if story then
            create[ "preloadparams[]" ] = story
        end
        path   = { sub,  mw.uri.buildQueryString( create ) }
        r      = LuaModuleDoc.frame:callParserFunction( "fullurl", path )
        show   = mw.message.new( show ):plain()
        button = mw.title.makeTitle( mw.site.namespaces.Template.id,
                                     "MediaWiki-Button" )
        if button.exists then
            button = { template = button.text,
                       Typ      = "progressive",
                       ["Groß"] = "1",
                       Link     = r,
                       Text     = show }
            r      = LuaModuleDoc.frame:expandTemplate{
                                                 title = button.template,
                                                 args  = button }
        else
            r = string.format( "<br>[%s '''%s''']", r, show )
        end
    end
    return r or ""
end -- createPage()



local function globalRepos( script )
    -- Check for global dissemination
    --     script  -- string; module name (main)
    -- Uses:
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.frame
    --     fetch()
    --     mw.wikibase.getEntity()
    --     mw.title.makeTitle()
    -- Return:
    --     string
    local entity = mw.wikibase.getEntity()
    local r
    if type( entity ) == "table" then
        local mode = 0
        local repo = entity:formatPropertyValues( "P1324" )
        local params, s
        if type( repo ) == "table"  and
           type( repo.value) == "string"  and
           repo.value:find( "//" ) then
            local t = mw.text.split( repo.value, ",%s+" )
            if #t > 1 then
                for i = 1, #t do
                    if t[ i ]:find( mw.site.server, 1, true ) then
                        s = t[ i ]
                        break -- for i
                    end
                end -- for i
                if not s then
                    s = t[ 1 ]
                end
            else
                s = repo.value
            end
            repo = mw.uri.new( s )
            if type( repo.path ) == "string"  and
               repo.path:match( "^/wiki/" ) then
                local space
                space, s = repo.path:sub( 7 ):match( "^([^:]+):(.+)$" )
                if space and s then
                    t = mw.title.makeTitle( space, s )
                    s = "//" .. repo.host
                    if mw.title.equals( LuaModuleDoc.title, t )  and
                       mw.site.server:find( s, 1, true ) then
                        mode = 2
                    else
                        mode = 1
                    end
                end
            end
            s = fetch( "templateGlobal", "" )
            if #s > 0 then
                local l, bib = pcall( require,
                                      LuaModuleDoc.title.prefixedText )
                local vsn = entity:formatPropertyValues( "P348" )
                params = { }
                if mode < 2 then
                    params[ 1 ] = string.format( "[%s %s]",
                                                 tostring( repo ),
                                                 repo.host )
                end
                if type( vsn ) == "table"  and
                   type( vsn.value) == "string" and
                   vsn.value ~= "" then
                    params.version = vsn.value
                end
                if type( bib ) == "table" then
                    local serial
                    if bib.failsafe then
                        if type( bib.failsafe ) == "function" then
                            serial = bib.failsafe( { args = { } } )
                        else
                            serial = bib.failsafe
                        end
                    elseif bib[ "#serial"] then
                        serial = bib[ "#serial"]
                    end
                    if type( serial ) == "number" then
                        serial = string.format( "%d", serial )
                    end
                    if type( serial ) == "string" then
                        params.here = serial
                    end
                end
                if fetch( "forkedGlobal", "0" ) ~= "1"  and
                   params.version  and  params.here  and
                   params.version ~= params.here  then
                    params.update = "1"
                end
                r = LuaModuleDoc.frame:expandTemplate{ title=s,
                                                       args=params }
            end
        end
        s = fetch( "categoryWikiData", "" )
        if #s > 0 then
            local slot
            if mode > 0 then
                if mode == 2 then
                    slot = catIfDefined( "categoryWikiDataParent" )
                else
                    slot = catIfDefined( "categoryWikiDataChild" )
                end
            end
            if not slot then
                slot = catIfDefined( s )
            end
            if slot then
                if r then
                    r = r .. slot
                else
                    r = slot
                end
                if params and params.update then
                    slot = catIfDefined( "categoryWikiDataReplication" )
                    if slot then
                        r = r .. slot
                    end
                end
            end
        end
    end
    return r or ""
end -- globalRepos()



local function navDevelop( start, script )
    -- Most interesting test and development page
    -- Precondition:
    --     start   -- string; central documentation root
    --     script  -- string; basic module name
    -- Return:
    --     string or false:  full page name, if any
    -- Uses:
    --     >  LuaModuleDoc.nsDocs
    --     mw.title.makeTitle()
    local n   = LuaModuleDoc.nsDocs
    local r   = false
    local sub = "/" .. fetch( "subTest", "Test" )
    local s   = string.format( "%s/%s%s", start, script, sub )
    local t   = mw.title.makeTitle( n, s )
    if not t.exists then
        local low    = false
        local subLow = mw.ustring.lower( sub )
        if subLow ~= sub then
            s   = string.format( "%s/%s%s", start, script, subLow )
            t   = mw.title.makeTitle( n, s )
            low = t.exists
        end
        if not low then
            n = mw.site.namespaces.Module.id
            s = string.format( "%s/%s", script, sub )
            t = mw.title.makeTitle( n, s )
            if not t.exists  and  subLow ~= sub then
                s = script .. subLow
                t = mw.title.makeTitle( n, s )
                t = t.exists
            end
        end
    end
    if t then
        r = string.format( "%s:%s",
                           mw.site.namespaces[ n ].name, s )
    end
    return r
end -- navDevelop()



local function navError( say, specific )
    -- Return error message, evaluate page .pageErr
    -- Precondition:
    --     say       -- string; message key
    --     specific  -- string, optional; additional information
    -- Uses:
    --     >  LuaModuleDoc.frame
    --     fetch()
    local show = fetch( "pageErr" )
    local r
    if type( show ) == "string" then
        local pars = { say }
        if type( specific ) == "string" then
            table.insert( pars, specific )
        end
        r = LuaModuleDoc.frame:expandTemplate{ title = show,
                                               args = pars }
    else
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
                         :wikitext( error( "arg 'pageErr' missing", 3 ) )
        r = tostring( e )
    end
    return r
end -- navError()



local function navLang( suite, collect, lazy )
    -- Append languages from string to collection
    -- Precondition:
    --     suite    -- string; space separated source
    --     collect  -- table; to be extended
    --                 every element: { langCode, lazy }
    --     lazy     -- true if only existing page is to be linked
    if type( suite ) == "string" then
        local raw = mw.text.split( suite, "%s+" )
        local e, i, j, s
        for i = 1, #raw do
            s = raw[ i ]
            if #s > 1 then
                for j = 1, #collect do
                    if s then
                        e = collect[ j ]
                        if e[ 1 ] == s then
                            s = false
                            if not lazy then
                                e[ 2 ] = false
                            end
                        end
                    end
                end -- for j
                if s then
                    table.insert( collect,  { s, lazy } )
                end
            end
        end -- for i
    end
end -- navLang()



local function navLangs( start, script )
    -- Analyze languages
    -- Precondition:
    --     current page is supposed to transclude LuaModuleDoc
    --     start   -- string; central documentation root
    --     script  -- string; basic module name
    -- Postcondition:
    --     LuaModuleDoc.transl is set up as table:
    --                         args for navigation template
    --                         [1] basic module name
    --                         [2] number of language codes  +  1
    --                         [3] first language code
    --                         [4] second language code
    --                         ... list of further language codes
    -- Uses:
    --     >  LuaModuleDoc.nsDocs
    --      < LuaModuleDoc.transl
    --     fetch()
    --     navLang()
    --     mw.title.makeTitle()
    local e, i, s, t
    local specified = fetch( "langsRequest", false )
    local super     = start .. "/" .. script .. "/"
    LuaModuleDoc.transl = { }
    if type( specified ) == "string" then
        if specified:match( "^%s*$" ) then
            specified = false
        end
    end
    navLang( fetch( "langsDefault" ),  LuaModuleDoc.transl,  specified )
    navLang( fetch( "langsMore" ),  LuaModuleDoc.transl,  true  )
    navLang( specified, LuaModuleDoc.transl, false )
    if #LuaModuleDoc.transl < 1 then
        LuaModuleDoc.transl = { { "en", false } }
    end
    for i = #LuaModuleDoc.transl, 1, -1 do
        e = LuaModuleDoc.transl[ i ]
        s = e[ 1 ]
        if e[ 2 ] then
            t = mw.title.makeTitle( LuaModuleDoc.nsDocs,  super .. s )
            if not t.exists then
                s = false
            end
        end
        if s then
            LuaModuleDoc.transl[ i ] = s
        else
            table.remove( LuaModuleDoc.transl, i )
        end
    end -- for i -1
    table.insert( LuaModuleDoc.transl,
                  1,
                  script )
    table.insert( LuaModuleDoc.transl,
                  2,
                  tostring( #LuaModuleDoc.transl ) )
end -- navLangs()



local function navMerge( start, swift, script, sub, lead )
    -- Include various external content into page
    -- Precondition:
    --     start   -- string; defined pageDocRoot argument
    --     swift   -- string; defined pageNav argument
    --     script  -- string; module name (main)
    --     sub     -- string or false; possible sub-module name
    --     lead    -- true: Module: namespace;   false: text namespace
    -- Uses:
    --     >  LuaModuleDoc.transl
    --     >  LuaModuleDoc.ns
    --     >  LuaModuleDoc.nsDocs
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.frame
    --     navError()
    --     mw.title.makeTitle()
    --     createPage()
    --     fetch()
    local server = mw.site.server
    local super  = false
    local t      = navDevelop( start, script )
    local collect, low, r, s
    collect = LuaModuleDoc.transl
    if t then
        collect.Test = t
    end
    if LuaModuleDoc.ns == LuaModuleDoc.nsDocs then
        s = string.format( "%s/%s", start, script )
        if LuaModuleDoc.title.text == s then
            super = LuaModuleDoc.title.text .. "/"
        elseif sub then
            collect.subDoc = sub
            collect.subModule = sub
            s = string.format( "%s/%s/%s", start, script, sub )
            if LuaModuleDoc.title.text == s then
                s = string.format( "%s/%s", s, collect[ 3 ] )
                t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
                if t.exists then
                    super = LuaModuleDoc.title.text .. "/"
                end
            end
        end
    elseif lead and sub then
        s = string.format( "%s/%s/%s", start, script, sub )
        t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
        if t.exists then
            collect.subDoc = sub
        end
    end
    if server:match( "%.beta%.wmflabs%.org$" ) then
        local slang, series = server:match( "//(%l+)%.(%l+)%." )
        low = true
        if series == "wikipedia" then
            if slang == "de" then
                collect.BETA = "w:de:"   --Talk
            end
        end
    end
    r = LuaModuleDoc.frame:expandTemplate{ title = swift,
                                           args = collect }
    if not low then
        t = LuaModuleDoc.title.talkPageTitle
        if LuaModuleDoc.ns == mw.site.namespaces.Module.id then
            local doc
            s   = string.format( "%s/%s", start, script )
            doc = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
            if not doc.exists then
                r = r .. createPage( "NoPageCentral",
                                     doc.prefixedText,
                                     start,
                                     LuaModuleDoc.nsDocs,
                                     script )
                t = false
            end
        end
        if t  and  not t.exists then
            if super then
                s = "NoTalkCentral"
            elseif LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
                s = false
            else
                s = "NoTalkRedir"
            end
            if s then
                r = string.format( "%s%s%s",
                                   r,
                                   navError( s ),
                                   createPage( s,
                                               t.prefixedText,
                                               start,
                                               LuaModuleDoc.nsDocs + 1,
                                               script ) )
            end
        end
    end
    if super then
        local d  = "{{%s*[lL]uaModuleDoc[^}]*}}%s*"
        local p1 = "^%s*" .. d .. "<onlyinclude>"
        local p2 = "%s*<noinclude>" .. d .. "</noinclude>"
        local space, sub, support
        for i = 3, #collect do
            t = mw.title.makeTitle( LuaModuleDoc.nsDocs,
                                    super .. collect[ i ] )
            s = t:getContent()
            if s then
                s = s:gsub( p1, "" ):gsub( p2, "" )
                if s:match( d ) then
                    r = string.format( "%s<br />%s<br />",
                                       r,
                                       navError( "BadInclude",
                                                 t.prefixedText ) )
                else
                    r = r ..
                        LuaModuleDoc.frame:expandTemplate{
                                                 title = t.prefixedText }
                    break    -- for i
                end
            end
        end -- for i
        s = fetch( "pageTemplateInsert", "" )
        space, support = s:match( "^([^:]+):(.+)$" )
        if space  and  mw.title.makeTitle( space, support ).exists then
            local suppress = fetch( "noHint", "" )
            if #suppress == 0 then
                local swift = collect[ 1 ]
                if sub then
                    swift = string.format( "%s/%s", swift, sub )
                end
                r = r ..
                    LuaModuleDoc.frame:expandTemplate{ title = s,
                                                       args = { swift } }
            end
        end
        s = fetch( "categoryDocs", "" )
        if #s > 0 then
            i = mw.title.makeTitle( "Category", s )
            if i.exists then
                r = string.format( "%s[[%s|%s]]",
                                   r, i.prefixedText, collect[ 1 ] )
            end
        end
        r = r .. "__NOEDITSECTION__"
    end
    if lead then
        r = r .. globalRepos( script )
    end
    return r
end -- navMerge()



local function navPage( lead )
    -- Return navigation text; analyze page location
    -- Precondition:
    --     current namespace will support LuaModuleDoc
    --     lead    -- true: Module: namespace;   false: text namespace
    -- Uses:
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.transl
    --     fetch()
    --     navLangs()
    --     navMerge()
    --     navError()
    local r
    local start = fetch( "pageDocRoot" )
    if type( start ) == "string" then
        local s      = "^"
        local script
        if not lead then
            s = "^" .. start .. "/"
        end
        s = s .. "([^/]+)/(.*/?)$"
        script, s = string.match( LuaModuleDoc.title.text .. "/",  s )
        if type( script ) == "string" then
            local sub   = false
            local swift = fetch( "pageNav" )
            navLangs( start, script )
            if type( s ) == "string" then
                if #s > 1 then
                    local q
                    s = s:match( "^([^/]+)/.*/?$" )
                    q = mw.title.makeTitle( "Module",
                                            script .. "/" .. s )
                    if q.exists and q.contentModel == "Scribunto" then
                        sub = s
                        for i = 1, #LuaModuleDoc.transl do
                            if LuaModuleDoc.transl[ i ] == s then
                                sub = false
                                break    -- for i
                            end
                        end -- for i
                    end
                end
            end
            if type( swift ) == "string" then
                r = navMerge( start,
                              swift,
                              script,
                              sub,
                              lead )
            else
                r = navError( "configMissing", "pageNav" )
            end
        else
            r = navError( "BadPage" ) .. LuaModuleDoc.title.text
        end
    else
        r = navError( "configMissing", "pageDocRoot" )
    end
    return r
end -- navPage()



local function navigation()
    -- Start execution; return navigation text; analyze namespace
    -- Uses:
    --      < LuaModuleDoc.title
    --      < LuaModuleDoc.ns
    --      < LuaModuleDoc.nsDocs
    --     fetch()
    --     mw.title.getCurrentTitle()
    --     navPage()
    --     navError()
    local r
    local nsDocs = fetch( "nsDocs" )
    if nsDocs then
        local lead
        LuaModuleDoc.title  = mw.title.getCurrentTitle()
        LuaModuleDoc.ns     = LuaModuleDoc.title.namespace
        lead                = ( LuaModuleDoc.ns ==
                                mw.site.namespaces.Module.id )
        LuaModuleDoc.nsDocs = tonumber( nsDocs )
        if lead  or
           LuaModuleDoc.ns == LuaModuleDoc.nsDocs  or
           LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
            r = navPage( lead )
        else
            r = navError( "BadNamespace" )
        end
    else
        r = navError( "configMissing", "nsDocs" )
    end
    return  r
end -- navigation()



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()



-- Provide template access
local p = {}

function p.nav( frame )
    -- Uses:
    --      < LuaModuleDoc.frame
    --     navigation()
    local lucky, r
    LuaModuleDoc.frame = frame
    lucky, r = pcall( navigation )
    if not lucky then
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
                         :wikitext( r )
        r = tostring( e )
    end
    return r or ""
end



p.failsafe = function ( frame )
    -- Check or retrieve version information
    -- Precondition:
    --     frame  -- object; #invoke environment
    -- Postcondition:
    --     Return string with error message or ""
    -- Uses:
    --     LuaModuleDoc.failsafe()
    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()

return p