Modul:GLAMpage

Lua Modul zur Verwaltung der Navigation der Vorlage:GLAMpage.


-- ## Modul:GLAMpage is a Lua Libary with Service-Functions for the GLAMpage Template ##
-- Please use this module via Template:GLAMpage only!
-- Modul:Tutorials requires a customisable config.json, passed via the parameter config to each function call
-- The Default is Template:GLAMpage/config.json

-- Helper Functions
-- Local functions and vars

local configData, templateData, rootNode, rootNodes
local currentTitle, currentNode, refNode, lastNode, nextNode, langLinks
local pagesById = {}
local rootNodesByLang = {}
local isAllPage
local currentPageNo = 0
local totalPageNo = 0
local isLastNode = false
local showHidden = false
local inited = false

function findNodeById(node, id)
    local idNode
    
    if  node.id == id then
        return node
    end
            
    if node.children then            
        for childIndex, childNode in pairs( node.children ) do
            idNode = findNodeById(childNode, id)
            if idNode then 
                return idNode
            end
        end
    end

    return idNode
end

function init(configPage)
    if inited then return end
    inited = true

    -- Functions
    local previousNode, node

    function initNode(node, i, parentNode)
        node.index = i
        node.childCount = 0

        if  node.page then
            node.title = mw.title.new(node.page)
            node.isCurrentPage = mw.title.equals( currentTitle, node.title )

            if not node.isCurrentPage and node.pageAliases then  
                local ai, a, at              
                for ai, a in pairs( node.pageAliases ) do
                    if mw.title.equals( currentTitle, mw.title.new(a) ) then
                        node.isCurrentPage = true
                    end
                end
            end

            node.containsCurrentPage = node.isCurrentPage
        else
            node.isLabel = true
        end

        --node.isAllPage = false
        node.isLastNode = false
        
        if parentNode then
            node.parent = parentNode
            node.root = parentNode.root
        else
            node.root = node
        end

        if not node.isCurrentPage and node.all then
            node.allTitle = mw.title.new(node.all)
            if mw.title.equals( currentTitle,  node.allTitle ) then 
                node.isCurrentPage = true
                node.isAllPage = true
            end
        end

        if previousNode then
            previousNode.nextNode = node
            node.lastNode = previousNode
            --[[ -- Funktioniert noch nicht
            if previousNode.parent == node.parent or previousNode ~= node.parent  then
            else
                previousNode.isLastNode = true
            end
            ]]--
        end
        previousNode = node

        if node.children then 
            local newChildrenArray = {}

            for childIndex, childNode in pairs( node.children ) do

                initNode(childNode, childIndex, node)

                if childNode.containsCurrentPage then
                    node.containsCurrentPage = true
                end

                if not (childNode.hidden and not childNode.containsCurrentPage) or showHidden then
                    node.childCount = node.childCount + 1
                    newChildrenArray[node.childCount] = childNode
                end
            end
            node.children = newChildrenArray
        end        

        node.refNode = node;
        if parentNode then
            if node.childCount == 0 then
                node.refNode = node.parent;
            end
        end   
        
        if node.isCurrentPage then
            currentNode = node
        end

        if node.refNode == node then
            node.isRefNode = true
        end

        if node.id then            
            pagesById[node.id] = pagesById[node.id] or {}
            pagesById[node.id][node.root.lang] = node 
        end

        return node
    end
    
    function prepareNodeHtml(node, i, parentNode)

        node.innerHtml = 
            node.isLabel and templateData.threadNaviLabel or
            node.isCurrentPage and templateData.threadNaviItemActive or 
            templateData.threadNaviItem
        
        if node.page then
            node.innerHtml = node.innerHtml:gsub("§§page§§", (isAllPage and '#' or '') .. node.page)        
        end
        
        node.innerHtml = node.innerHtml:gsub("§§name§§", node.name)

        node.childHtml = ''        
        if node.children then 
            for childIndex, childNode in pairs( node.children ) do
                prepareNodeHtml(childNode, childIndex, node)
            end
        end

        local isActive = node.isCurrentPage or node.containsCurrentPage
        local classes = (isActive and ' active' or '') .. (node.isLabel and ' label' or '')

        node.childHtml = (node.childHtml == '') and '' or ('<ul>' .. node.childHtml .. '</ul>')
        node.outerHtml = '<li' .. (classes and ' class="'.. classes ..'"' or '') ..  '>' .. node.innerHtml .. node.childHtml .. '</li>'

        if parentNode and (node.containsCurrentPage or (not node.hidden))  then
            parentNode.childHtml = parentNode.childHtml .. node.outerHtml
        end        

        return node
    end

    mw.log('Lua Init')
    -- Processing

    currentTitle = mw.title.getCurrentTitle()       
    if not configPage then configPage = 'Template:GLAMpage/config.json' end
    configData = mw.text.jsonDecode( mw.title.new(configPage):getContent() )

    rootNodes = configData.structure
    templateData = configData.templates

    local refLang, firstRoot

    for rootIndex, rootNode in pairs( rootNodes ) do

        if not firstRoot then firstRoot = rootNode end

        refNode = rootNode
        refLang = rootNode.lang

        if refLang then rootNodesByLang[refLang] = rootNode end
            
        initNode(rootNode, 0, false)
    end

    if not currentNode then
        currentNode = firstRoot;
    end

    if currentNode then
        refNode = currentNode.refNode
        totalPageNo = refNode.childCount
        currentPageNo = currentNode.index
        isLastNode = currentNode.isLastNode
        isAllPage = currentNode.isAllPage
        nextNode = currentNode.nextNode
        lastNode = currentNode.lastNode
    end
    
    prepareNodeHtml(currentNode.root, 0)
end

function getPageContent( node, frame )
    if not node then 
        return ''
    end     
    local source, html
    source = node.title:getContent()
    html = frame:preprocess( tostring( mw.html.create( 'div' ):wikitext( source ) ) )

    return '<h2>' .. node.name .. '</h2>' .. html
end

function getNodeByTitle(title, node)
    local childNode, childIndex, foundNode, isBase

    if not title then 
        return currentNode
    end

    if not node then 
        node = rootNode 
        isBase = true
    end

    if mw.title.equals( title, node.title ) then
        return node
    else
        if node.children then                 
            for childIndex, childNode in pairs( node.children ) do
                foundNode = getNodeByTitle(title, childNode)
                if foundNode then 
                    return foundNode
                end
            end
        end
        if isBase then 
            return currentNode
        else 
            return false
        end
    end
end

-- Public Interface

local p = {} 

function p.navIndex(frame)
    mw.log('Lua navIndex ', frame)

    init( frame.args[config] );
    local node = getNodeByTitle(frame.args[title])
    return node.refNode.childHtml
end

function p.navi(frame)    
    mw.log('Lua navWidget ', frame)
    init( frame.args[config] );

    local node = currentNode
    local widgetHtml = templateData.widget:gsub("§§rootPage§§",node.root.page):gsub("§§threadNavi§§", node.root.innerHtml .. node.root.childHtml ) --:gsub("§§pagina§§", pagina )

    return widgetHtml
end

function p.home(frame)
    mw.log('Lua home ', frame)
    init( frame.args[config] );

    return currentNode.root.page
end

function p.homeLink(frame)
    mw.log('Lua home ', frame)
    init( frame.args[config] );

    local node = currentNode
    local homeHtml = templateData.homeLink:gsub("§§page§§",node.root.page)

    return homeHtml
end

function p.langSwitch(frame)
    mw.log('Lua langSwitch ', frame)
    init( frame.args[config] );

    if not currentNode or #rootNodes <= 1 then
        return 
    end

    local idNode
    local ids = {}
    local idNo = 0
    local id
    local node = currentNode
    local langSwitchHtml = '<div class="glam-lang-trigger" style="display:none">[[File:OOjs UI icon language-ltr-invert.svg|100px|link=#GLAMlang]][[#GLAM|<span></span>]]</div><div class="glam-lang" style="display:none"><ul>'
    
    langLinks = {}
    
    repeat       
        if node.id then
            table.insert(ids, node.id);    
            idNo = idNo + 1  
        end
        node = node.parent
    until (not node) 

    id = ids[1];
    mw.log('id: ' .. (id or 'undefined') .. '/' .. (currentNode.id or 'undefined') ..'/' .. (currentNode.page))

    for rootIndex, rootNode in pairs( rootNodes ) do
        idNode = (id and findNodeById(rootNode, id)) or rootNode 
        langLinks[rootNode.langName or rootNode.lang] = idNode.page
        langSwitchHtml = langSwitchHtml .. '<li>[[' .. idNode.page ..'|'.. (rootNode.langName or rootNode.lang) .. ']]</li>'
    end

    mw.log( mw.text.jsonEncode( langLinks, mw.text.JSON_PRETTY + mw.text.JSON_PRESERVE_KEYS ) )
  
    langSwitchHtml = langSwitchHtml .. '</ul></div>'

    return langSwitchHtml
end

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.