Die Dokumentation für dieses Modul kann unter Modul:Benutzer:ireas/Doku erstellt werden

-- Navi 2015-08-02 by ireas
-- Generates a multilevel navigation.
-- * get: returns the navigation for the current page

-- the data that is used to generate the template -- should be included from
-- a data page
local data = {
    base = "Wikipedia:Wiki Loves Monuments 2015/Deutschland",
    template = "Benutzer:Ireas/test/navi",
    pages = {
        -- "WLM 2015"
        {
            "WLM 2015",
            page = "",
            pages = { "Preise",  "Jury" },
        },
        -- "Orga"
        {
            "Orga",
            page = "/Organisation",
            pages = {
                "Zeitplan",
                {
                    "Kick-off in Wiesbaden",
                    page = "/Kick-off Wiesbaden"
                },
                {
                    "Netzwerk-Treffen in Weimar",
                    page = "/WLM-Netzwerk-Treffen in Weimar"
                },
            },
        },
    },
}

-- Returns 'y' if `value` evaluates to `true` and an empty string otherwise.
local function booleanToYesEmpty(value)
    return (value) and  'y' or ''
end


-- Computes the ‘nstitle’ (local namespace and title) of the given `page`
-- (a string or a table containing the configured information),
local function getNstitle(base, page)
    if type(page) == "string" then
        -- if page is a string, it’s the name of the supage
        return base .. '/' .. page
    else
        -- page is a table --> [1] is the title, [page] is the page name
        local pageTitle = page.page
        if pageTitle and pageTitle ~= '' then
            if pageTitle:sub(1, 1) == "/" then
                -- it’s a sub-page of the base
                return base .. pageTitle
            else
                -- it’s a regular page name
                return pageTitle
            end
        else
            -- page is empty --> base name
            return base
        end
    end
end

-- Returns the title for the given `page` to use in the navigation.
local function getNaviTitle(page)
    return (type(page) == "string") and page or page[1]
end

-- Tries to find a page with the given `nstitle` (local namespace and title) in
-- the given list of `pages` and returns the position of the entry (or `nil` if
-- it cannot be found). The position is a table of indizes. `base` is the base
-- name of the pages in the navigation. This function is called recursively, and
-- `current` is the current position (optional for the first call).
local function findPosition(nstitle, base, pages, current)
    local position = current or {}
    -- Loop through the current list of pages and try to find a matching
    -- entry.
    for i = 1, #pages do
        if getNstitle(base, pages[i])  == nstitle then
            -- We found our page!
            position[#position + 1] = i
            return position
        end
    end
    -- No direct match, so try go to the next level
    for i = 1, #pages do
        local subpages = pages[i].pages
        if subpages then
            local subpagePosition = position
            subpagePosition[#subpagePosition + 1] = i
            subpagePosition = findPosition(nstitle, base, subpages,
                                           subpagePosition)
            if subpagePosition then
                -- If we found the entry, return the position. Otherwise
                -- continue.
                return subpagePosition
            end
        end
    end
    -- The page was neither found on this level nor on any sublevel
    return nil
end

-- Creates the wikitext for the navigation based on the configured data
-- (the given `base` page and the current `pages` to look at) and the given
-- `position` of the current entry. `frame` is used to include templates. This
-- function is called recursively, and `level` is the current recursion level
-- starting at 1. `template` is the item template included for every navi item.
-- `parentSelected` is `true` if the parent of this level was selected or
-- if this is the first level.
local function buildNavi(frame, template, base, pages, position, level,
                         parentSelected)
    local text = ""
    for i = 1, #pages do
        -- print this page
        local page = pages[i]
        local selected = (parentSelected and level <= #position and
        	              position[level] == i)
        local hasChildren = (selected and page.pages)
        local nstitle = getNstitle(base, page)
        local naviTitle = getNaviTitle(page)
        local args = {
            page = nstitle,
            title = naviTitle,
            hasChildren = booleanToYesEmpty(hasChildren),
            selected = booleanToYesEmpty(selected),
            level = level,
        }
        text = text .. frame:expandTemplate({ title = template, args = args})
        text = text .. '\n'
        -- print the subpages if this item is selected and there are children
        if selected and page.pages then
            local subpages = page.pages
            local subpagePosition = position
            subpagePosition[#subpagePosition + 1] = i
            text = text .. buildNavi(frame, template, base, subpages,
                                     subpagePosition, level + 1, selected)
        end
    end
    return text
end

-- Reads the data in `data`, tries to identify the position of the given
-- `title` and returns the appropriate wiki code. `frame` is used to
-- evaluate templates.
local function getNavi(title, frame)
	local nstitle = title.nsText .. ':' .. title.text
    local position = findPosition(nstitle, data.base, data.pages)
    if position then
        return buildNavi(frame, data.template, data.base, data.pages, position,
        	             1, true)
    else
        return "Es existiert kein Navieintrag für die Seite " .. nstitle
    end
end

local p = {}

function p.get(frame)
    local title = mw.title.getCurrentTitle()
    -- if "debugns" and "debugtitle" are set: use custom page for debugging
    if frame.args.debugns and frame.args.debugtitle then
        title = mw.title.makeTitle(frame.args.debugns, frame.args.debugtitle)
    end
    return getNavi(title, frame)
end

return p