Zum Inhalt springen

Modul:Tutorials

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 3. Juni 2018 um 11:59 Uhr durch Martin Kraft (Diskussion | Beiträge) (+ hidden). Sie kann sich erheblich von der aktuellen Version unterscheiden.

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

-- ## Modul:Tutorials is a Lua Libary to manage Wikipedia-Tutorials ##
-- Please use this module via Vorlage:Tutorials only!
-- Modul:Tutorials requires a customisable config.json, passed via the parameter config to each function call
-- The Default is Wikipedia:Tutorial/config.json


-- Helper Functions

-- Local functions and vars

local configData, structureData, templateData
local currentTitle, currentNode, refNode, currentPageNo, totalPageNo, lastNode, nextNode, isAllPage, isLastNode = false
local inited = false

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

    currentTitle = mw.title.getCurrentTitle()       

    if not configPage then configPage = 'Wikipedia:Tutorial/config.json' end
    configData = mw.text.jsonDecode( mw.title.new(configPage):getContent() )
    structureData = configData.structure
    templateData = configData.templates

    function initNode(node, i, parentNode)
        node.index = i
        node.childCount = 0
        node.title = mw.title.new(node.page)
        node.isCurrentPage = mw.title.equals( currentTitle, node.title )
        node.containsCurrentPage = node.isCurrentPage;

        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 node.children then 
            childIndex = 1
            while childIndex < #node.children do
                childNode = node.children[childIndex]
                initNode(childNode, childIndex, node)
                
                if childNode.containsCurrentPage then
                    node.containsCurrentPage = true
                end

                if childNode.hidden and childNode.containsCurrentPage == false then
                    table.remove( node.children, childIndex )
                else
                    childIndex = childIndex + 1
                end
            end
        end

        if parentNode then
            node.parent = parentNode
            parentNode.childCount = i
        end   
        
        if node.isCurrentPage then
            currentNode = node
        end

        return node;
    end
    
    function prepareNodeHtml(node, i, parentNode)
        if node.isCurrentPage then
            node.innerHtml = templateData.threadNaviItemActive
        else
            node.innerHtml = templateData.threadNaviItem
        end

        if isAllPage then
            node.innerHtml = node.innerHtml:gsub("§§page§§", '#' .. node.name)
        else
            node.innerHtml = node.innerHtml:gsub("§§page§§", 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

        if node.childHtml == '' then
            node.outerHtml = '<li>' .. node.innerHtml .. '</li>'
        else
            node.childHtml = '<ol style="margin-left:2.2ex;">' .. node.childHtml .. '</ol>'
            node.outerHtml = '<li>' .. node.innerHtml .. node.childHtml .. '</li>'
        end

        if parentNode then
            parentNode.childHtml = parentNode.childHtml .. node.outerHtml
        end        

        return node;
    end;
        
    initNode(structureData, 0)

    refNode = structureData
    currentPageNo = 0
    totalPageNo = 0
    if currentNode then
        currentPageNo = currentNode.index
        if currentNode.parent and currentNode.childCount==0 then 
            -- Subpages
            refNode = currentNode.parent
            totalPageNo = currentNode.parent.childCount
            lastNode = (currentPageNo==1) and currentNode.parent or currentNode.parent.children[currentPageNo-1]
            if currentPageNo < totalPageNo then
                nextNode = currentNode.parent.children[currentPageNo+1]
            else
                isLastNode = true
                -- Search next Tutorial
            end
        else
            -- Mainpages
            refNode = currentNode
            if currentNode.childCount>0 then
                currentPageNo = 0
                totalPageNo = currentNode.childCount
                nextNode = currentNode.children[1]
            else
                if currentNode.parent then
                    totalPageNo = currentNode.parent.childCount
                    lastNode = (currentPageNo==1) and currentNode.parent or currentNode.parent.children[currentPageNo-1]
                    if currentPageNo < totalPageNo then
                        nextNode = currentNode.parent.children[currentPageNo+1]
                    end
                end
            end
        end

        if currentNode.isAllPage then 
            isAllPage = true
        end
    end
    
    prepareNodeHtml(structureData, 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

-- Public Interface

local p = {} 

function p.navIndex(frame)
    init( frame.args[config] );
    return refNode.childHtml
end

function p.navWidget(frame)
    init( frame.args[config] );

    local pagina, btnHtml;
    if isAllPage then
        pagina = templateData.paginaAll:gsub("§§page§§", refNode.page);
    else
        if currentPageNo == 0 then
            pagina = templateData.paginaStart
        else
            pagina = templateData.pagina
        end  
        pagina = pagina:gsub("§§totalPageNo§§", totalPageNo ):gsub("§§currentPageNo§§", currentPageNo ) 
        btnHtml = ''
        if lastNode then
            btnHtml = templateData.btnLast:gsub("§§page§§", lastNode.page ):gsub("§§name§§", lastNode.name )
        end 
        pagina = pagina:gsub("§§btnLast§§", btnHtml )
    
        btnHtml = ''
        if nextNode then
            btnHtml = templateData.btnNext:gsub("§§page§§", nextNode.page ):gsub("§§name§§", nextNode.name )
        end
        pagina = pagina:gsub("§§btnNext§§", btnHtml )   
    
        btnHtml = ''
        if refNode.all then
            btnHtml = templateData.btnAll:gsub("§§page§§", refNode.all )
        end
        pagina = pagina:gsub("§§btnAll§§", btnHtml )
    end

    local widgetHtml = templateData.widget:gsub("§§rootPage§§",structureData.page):gsub("§§threadNavi§§", refNode.innerHtml .. refNode.childHtml ):gsub("§§pagina§§", pagina )

    return widgetHtml
end

function p.all(frame)
    init( frame.args[config] );
    -- body
    local html
    if currentNode then

        html = '<div class="tutorial-article" style="margin-bottom:6em;">' .. getPageContent(refNode, frame) .. '</div>'
         
        for childIndex, childNode in pairs( refNode.children ) do
            html = html .. '<div class="tutorial-article" style="margin-bottom:6em;">' .. getPageContent(childNode, frame) .. '</div>'
        end

        return html
    else
        return "not found"
    end
end

function p.isAll(frame)
    init( frame.args[config] );
    return isAllPage
end

return p