Modul:PageAttributes

aus Wikipedia, der freien Enzyklopädie
local PageAttributes = { suite  = "PageAttributes",
                         serial = "2022-06-06",
                         item   = 112249306 }
--[==[
Assign attributes to pages or entire namespaces
]==]
local Failsafe  = PageAttributes
local GlobalMod = PageAttributes



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
    -- 2020-01-01
    local storage = access
    local fun, lucky, r
    if advanced then
        fun = require
    else
        fun = mw.loadData
    end
    if append then
        storage = string.format( "%s/%s", storage, append )
    end
    lucky, r = pcall( fun,  "Module:" .. storage )
    if not lucky then
        local suited
        GlobalMod.globalModules = GlobalMod.globalModules or { }
        suited = GlobalMod.globalModules[ access ]
        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
            if append then
                storage = string.format( "%s/%s", storage, append )
            end
            lucky, r = pcall( fun, storage )
        end
        if not lucky and alert then
            error( "Missing or invalid page: " .. storage )
        end
    end
    return r
end -- foreignModule()



PageAttributes.f = function ( ask, another )
    -- Retrieve page attributes
    -- Precondition:
    --     ask      -- string, with submodule name
    --     another  -- string or mw.title (optional), with page name
    --                 default: current page
    -- Postcondition:
    --     Returns  string, number, boolean
    local r
    if type( ask ) == "string" then
        local props = foreignModule( PageAttributes.suite,
                                     false,
                                     ask,
                                     PageAttributes.item )
        if type( props ) == "table" then
            local page
            if another then
                local s = type( another )
                if s == "string" then
                    local id = another:match( "^%s*#(%d+)%s*$" )
                    page = mw.title.new( id or another )
                elseif s == "number"  then
                    page = mw.title.new( another )
                elseif s == "table"  and
                       type( another.namespace ) == "number"  and
                       type( another.id ) == "number"  then
                    page = another
                end
            end
            page = page or mw.title.getCurrentTitle()
            if type( props.rooms ) == "table" then
                r = props.rooms[ page.namespace ]
            end
            if type( props.pageids ) == "table" then
                local q = props.pageids[ page.id ]
                if q ~= nil then
                    r = q
                end
            end
            if type( r ) == "string" then
                r =  mw.text.trim( r )
                if r == "" then
                    r = false
                end
            end
        end
        r = r or false
    end
    return r
end    -- PageAttributes.f()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version
    --                         or wikidata|item|~|@ or false
    -- Postcondition:
    --     Returns  string  -- with queried version/item, also if problem
    --              false   -- if appropriate
    -- 2020-08-17
    local since  = atleast
    local last   = ( since == "~" )
    local linked = ( since == "@" )
    local link   = ( since == "item" )
    local r
    if last  or  link  or  linked  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local suited = string.format( "Q%d", item )
            if link then
                r = suited
            else
                local entity = mw.wikibase.getEntity( suited )
                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
                        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
    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 = { }

function p.f( frame )
    local sub = frame.args[ 1 ]
    local r
    if sub then
        sub = mw.text.trim( sub )
        if sub ~= "" then
            local s = frame.args[ 2 ]
            if s then
                s = mw.text.trim( s )
                if s == "" then
                    s = false
                end
            end
            r = PageAttributes.f( sub, s )
        end
    end
    if type( r ) == "boolean" then
        r = ( r and "1" ) or ""
    end
    return r
end    -- 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

setmetatable( p,  { __call = function ( func, ... )
                                 setmetatable( p, nil )
                                 return Failsafe
                             end } )

return p