Modul:Vorlage:URN

Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus

Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData: 2020-01-18

local URN = { suite   = "URN",
              serial  = "2020-01-18",
              item    = 52365013,
              globals = { TemplUtl = 52364930,
                          URIutil  = 19644443 }
            }
--[=[
Support Template:URN   {{URN}}
]=]
local Failsafe  = URN
local GlobalMod = URN



local Config = {
    self        = URN.suite,
    errCat      = false,
    errClass    = "error_URN",
    errClasses  = false,
    errHide     = false,
    errNS       = false,
    errConflict = { en = "Conflict in multiple parameters",
                    de = "Konflikt durch überbestimmte Parameter" },
    errInvalid  = { en = "Invalid:",
                    de = "Ungültig:" },
    errMissing  = { en = "Missing ID",
                    de = "ID fehlt" },
    errModule   = { en = "Library module missing:",
                    de = "Bibliotheksmodul fehlt:" },
    errUnkown   = { en = "Unkown parameter:",
                    de = "Parameter unbekannt:" }
}



local foreignModule = function ( access, advanced, append, alt, alert )
    -- Fetch global module
    -- Precondition:
    --     access    -- string, with name of base module
    --     advanced  -- true, for require(); else mw.loadData()
    --     append    -- string, with subpage part, if any; or false
    --     alt       -- number, of wikidata item of root; or false
    --     alert     -- true, for throwing error on data problem
    -- Postcondition:
    --     Returns whatever, probably table
    -- 2019-10-29
    local storage = access
    local finer = function ()
                      if append then
                          storage = string.format( "%s/%s",
                                                   storage,
                                                   append )
                      end
                  end
    local fun, lucky, r, suited
    if advanced then
        fun = require
    else
        fun = mw.loadData
    end
    GlobalMod.globalModules = GlobalMod.globalModules or { }
    suited = GlobalMod.globalModules[ access ]
    if not suited then
        finer()
        lucky, r = pcall( fun,  "Module:" .. storage )
    end
    if not lucky then
        if not suited  and
           type( alt ) == "number"  and
           alt > 0 then
            suited = string.format( "Q%d", alt )
            suited = mw.wikibase.getSitelink( suited )
            GlobalMod.globalModules[ access ] = suited or true
        end
        if type( suited ) == "string" then
            storage = suited
            finer()
            lucky, r = pcall( fun, storage )
        end
        if not lucky and alert then
            error( "Missing or invalid page: " .. storage, 0 )
        end
    end
    return r
end -- foreignModule()



local function factory( apply )
    -- Localization of messages
    --     apply  -- string, with message key
    -- Returns message text; at least English
    local entry = Config[ apply ]
    local r
    if entry then
        -- TODO: page language
        r = entry[ mw.language.getContentLanguage():getCode() ]
        if not r then
            r = entry.en
        end
    else
        r = tostring( mw.html.create( "span" )
                             :addClass( "error" )
                             :wikitext( string.format( "????.%s.????",
                                                       apply ) ) )
    end
    return r
end -- factory()



local function faculty( adjust )
    -- Test template arg for boolean
    --     adjust  -- string or nil
    -- Returns boolean
    local r = false
    if adjust then
        r = mw.text.trim( adjust )
        if r ~= ""  and  r ~= "0" then
            r = true
        end
    end
    return r
end -- faculty()



local function fault( alert, about )
    -- Format message with class="error" or similar
    --     alert  -- string, with message key
    --     about  -- string, with explanation
    -- Returns message with markup
    local scope    = Config.errClass
    local story    = factory( alert )
    local TemplUtl = foreignModule( "TemplUtl",
                                    true,
                                    false,
                                    URN.globals.TemplUtl )
    local r
    if type( TemplUtl ) == "table"  and
       type( TemplUtl.TemplUtl ) == "function" then
        TemplUtl = TemplUtl.TemplUtl()
    else
        TemplUtl = false
    end
    if Config.self then
        story = string.format( "%s * %s", Config.self, story )
    end
    if about then
        story = string.format( "%s %s", story, about )
    end
    if Config.errClasses then
        if scope then
            scope = string.format( "%s %s",
                                   scope, Config.errClasses )
        else
            scope = Config.errClasses
        end
    end
    if TemplUtl then
        r = TemplUtl.failure( story,
                              not Config.errHide,
                              scope,
                              Config.frame )
    else
        r = tostring(  mw.html.create( "span" )
                              :addClass( scope )
                              :addClass( "error" )
                              :wikitext( story ) )
    end
    if Config.errCat then
        if Config.errNS then
            local ns = mw.title.getCurrentTitle().namespace
            local st = type( Config.errNS )
            if st == "string" then
                local space  = string.format( ".*%%s%d%%s.*", ns )
                local spaces = string.format( " %s ", Config.errNS )
                if spaces:match( space ) then
                    Config.errNS = false
                end
            elseif st == "table" then
                for i = 1, #Config.errNS do
                    if Config.errNS[ i ] == ns then
                        Config.errNS = false
                        break    -- for i
                    end
                end -- for i
            end
        end
        if not Config.errNS then
            r = string.format( "%s[[Category:%s]]", r, Config.errCat )
        end
    end
    return r
end -- fault()



local function format( access )
    -- Analyze code, create URL
    --     access  -- table
    --                .id        -- string, with URN ID component
    --                .resolver  -- string, or false
    --                .fragment  -- string, or false
    -- Returns string, perhaps with error message
    local URIutil = foreignModule( "URIutil",
                                   true,
                                   false,
                                   URN.globals.URIutil )
    local r
    if type( URIutil ) == "table"  and
       type( URIutil.URIutil ) == "function"  then
        URIutil = URIutil.URIutil()
        r = URIutil.uriURN( "urn:" .. access.id,
                            false,
                            access.resolver,
                            false,
                            access.fragment )
        if not r:find( "//", 1, true ) then
            r = fault( "errInvalid", access.id )
        end
    else
        r = fault( "errModule", "URIutil" )
    end
    return r
end -- format()



local function main( argsF, argsT )
    -- Invocation
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string
    local r
    if argsF then
        Config.errCat     = argsF.errCat
        Config.errClasses = argsF.errClasses
        Config.errHide    = faculty( argsF.errHide )
        Config.errNS      = argsF.errNS
    end
    if type( argsT ) == "table" then
        local unknown
        r = { }
        for k, v in pairs( argsT ) do
            s = type( k )
            if s == "number" then
                if ( k <= 2 ) then
                    v = mw.text.trim( v )
                    if v ~= "" then
                        r[ k ] = v
                    end
                    k = false
                else
                    k = tostring( k )
                end
            elseif s == "string" then
                if k == "resolver"  or  k == "fragment" then
                    if v ~= "" then
                        r[ k ] = v
                    end
                    k = false
                elseif argsF.demo  or  faculty( argsF.NoCat ) then
                    Config.errCat  = false
                    Config.errHide = false
                    k = false
                end
            end
            if k then
                if not unknown then
                    unknown = { }
                end
                table.insert( unknown, k )
            end
        end -- for k, v
        if unknown then
            r = string.format( "'<code>%s</code>' in Template:URN",
                               table.concat( unknown, " " ) )
            r = fault( "errUnkown", r )
        elseif r[ 1 ] then
            r.id = r[ 1 ]
            if r[ 2 ] then
                -- transition & migration at dewiki
                r.id = string.format( "%s:%s", r.id, r[ 2 ] )
            end
            r = format( r, r.fragment )
        else
            r = fault( "errMissing" )
        end
    end
    return r
end -- main()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version or "wikidata" or "~"
    --                 or false
    -- Postcondition:
    --     Returns  string  -- with queried version, also if problem
    --              false   -- if appropriate
    -- 2019-10-15
    local last  = ( atleast == "~" )
    local since = atleast
    local r
    if last  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local entity = mw.wikibase.getEntity( string.format( "Q%d",
                                                                 item ) )
            if type( entity ) == "table" then
                local seek = Failsafe.serialProperty or "P348"
                local vsn  = entity:formatPropertyValues( seek )
                if type( vsn ) == "table"  and
                   type( vsn.value ) == "string"  and
                   vsn.value ~= "" then
                    if last  and  vsn.value == Failsafe.serial then
                        r = false
                    else
                        r = vsn.value
                    end
                end
            end
        end
    end
    if type( r ) == "nil" then
        if not since  or  since <= Failsafe.serial then
            r = Failsafe.serial
        else
            r = false
        end
    end
    return r
end -- Failsafe.failsafe()



-- Export
local p = { }

p.f = function ( frame )
    local lucky, r
    Config.frame = frame
    lucky, r = pcall( main, frame.args, frame:getParent().args )
    if not lucky then
        r = tostring( mw.html.create( "span" )
                             :addClass( "error" )
                             :wikitext( string.format( "%s * %s",
                                                       frame:getTitle(),
                                                       r ) ) )
    end
    return r
end -- p.f()

p.failsafe = function ( frame )
    -- Versioning interface
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return Failsafe.failsafe( since )  or  ""
end -- p.failsafe()

p.test = function ( argsF, argsT )
    lucky, r = pcall( main, argsF, argsT )
    return r
end -- p.test()

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.