Module:Sandbox/LVL: Difference between revisions

LVL (talk | contribs)
Created page with "local Tabs = {} -- Helper functions to replace Module:Logic local function readBool(val) if val == nil then return false end if type(val) == 'boolean' then return val end if type(val) == 'string' then val = val:lower() return val == 'true' or val == 'yes' or val == '1' end return false end local function isEmpty(val) if val == nil then return true end if type(val) == 'string' then return val:gsub('%s','') == '' end if typ..."
 
LVL (talk | contribs)
No edit summary
Line 1: Line 1:
local Tabs = {}
local Tabs = {}


-- Helper functions to replace Module:Logic
-- Helper functions
local function readBool(val)
local function readBool(val)
     if val == nil then return false end
     if val == nil then return false end
Line 12: Line 12:
end
end


local function isEmpty(val)
local function getDisplayNameFromLink(link)
     if val == nil then return true end
     return link:match('([^/]+)$') or link
    if type(val) == 'string' then return val:gsub('%s','') == '' end
    if type(val) == 'table' then return next(val) == nil end
    return false
end
 
-- Helper to replace Module:Table.extract
local function extractTable(tab, key)
    local val = tab[key]
    tab[key] = nil
    return val
end
 
-- Helper to replace Module:Array functions
local function arrayForEach(t, f)
    for i, v in ipairs(t) do f(v, i) end
end
 
local function arrayAny(t, f)
    for _, v in ipairs(t) do if f(v) then return true end end
    return false
end
 
local function arrayAll(t, f)
    for _, v in ipairs(t) do if not f(v) then return false end end
    return true
end
end


-- Helper to replace Module:Operator.property
-- Main function
local function property(key)
function Tabs.static(frame)
     return function(obj) return obj[key] end
     local args = frame.args or {}
end
      
 
    -- Find all tabs
-- Simplified page link generation (replaces Module:Page)
     local tabs = {}
local function makeInternalLink(_, name, link)
     local i = 1
     return mw.ustring.format('[[%s|%s]]', link, name)
     while args['name' .. i] or args['link' .. i] do
end
         table.insert(tabs, {
 
            name = args['name' .. i],
-- Main argument processor
            link = args['link' .. i],
local function readArguments(args, options)
            this = (tonumber(args.This) == i)
     local tabArgs = {}
        })
     local tabIndex = 1
         i = i + 1
    local this = tonumber(args.This)
    local this2 = tonumber(args.This2)
 
     while args['name' .. tabIndex] or args['link' .. tabIndex] do
         local content = args['content' .. tabIndex]
        if content or not options.removeEmptyTabs then
            table.insert(tabArgs, {
                name = extractTable(args, 'name' .. tabIndex),
                link = extractTable(args, 'link' .. tabIndex),
                content = extractTable(args, 'content' .. tabIndex),
                tabs = extractTable(args, 'tabs' .. tabIndex),
                this = this == tabIndex or (options.allowThis2 and this2 == tabIndex),
            })
         end
        tabIndex = tabIndex + 1
     end
     end
 
   
     if readBool(args.returnIfEmpty) then
     if #tabs == 0 then
         return tabArgs
         return 'Error: No tabs defined (need at least name1 or link1)'
     end
     end
 
      
     assert(#tabArgs > 0, 'You are trying to add a "Tabs" template without arguments for names nor links')
     -- Auto-set first tab as active if none specified
     return tabArgs
     if not args.This then
end
         tabs[1].this = true
 
-- Automatic this-tab detection
local function setThis(tabArgs)
    if arrayAny(tabArgs, property('this')) then return end
 
    local fullPageName = mw.title.getCurrentTitle().prefixedText
    local this
    local maxLinkLength = -1
 
     arrayForEach(tabArgs, function(tab, tabIndex)
        local link = tab.link
        if not link then return end
         link = link:gsub('_', ' ')
        local linkLength = #link
        local charAfter = fullPageName:sub(linkLength + 1, linkLength + 1)
        local pagePartial = fullPageName:sub(1, linkLength)
        if pagePartial == link and (charAfter == '/' or charAfter == '') and linkLength > maxLinkLength then
            maxLinkLength = linkLength
            this = tabIndex
        end
    end)
 
    if this then tabArgs[this].this = true end
end
 
-- Content div builder
local function buildContentDiv(hasContent, hybridTabs, noPadding)
    local contentDiv = mw.html.create('div'):addClass('tabs-content')
    if hybridTabs then
        contentDiv:css('border-style', 'none !important')
                :css('padding', '0 !important')
    elseif noPadding then
        contentDiv:css('padding', '0 !important')
     end
     end
     return contentDiv
      
end
    -- Build HTML
 
     local container = mw.html.create('div')
-- Display name extractor
         :addClass('tabs-static')
local function getDisplayNameFromLink(link)
      
     local parts = {}
     local tablist = mw.html.create('ul')
    for part in link:gmatch('[^/]+') do
         :addClass('nav nav-tabs tabs tabs' .. #tabs)
         table.insert(parts, part)
      
    end
     for _, tab in ipairs(tabs) do
    return parts[#parts] or link
         local display = tab.name or getDisplayNameFromLink(tab.link)
end
         local text = tab.link and ('[[' .. tab.link .. '|' .. display .. ']]') or display
 
       
-- Main static tabs function
         tablist:tag('li')
function Tabs.static(args)
     args = args or {}
    local tabArgs = readArguments(args, { allowThis2 = true })
    if #tabArgs == 0 then return nil end
 
    setThis(tabArgs)
 
     local tabs = mw.html.create('ul')
         :addClass('nav nav-tabs navigation-not-searchable tabs tabs' .. #tabArgs)
        :attr('data-nosnippet')
 
     local subTabs = mw.html.create()
 
     arrayForEach(tabArgs, function(tab)
         local name = tab.name or getDisplayNameFromLink(tab.link or '')
         local text = tab.link and makeInternalLink(nil, name, tab.link) or tab.name
         tabs:tag('li')
             :addClass(tab.this and 'active' or nil)
             :addClass(tab.this and 'active' or nil)
             :wikitext(text)
             :wikitext(text)
        subTabs:node(tab.this and tab.tabs or nil)
    end)
    return mw.html.create()
        :tag('div')
            :addClass('tabs-static')
            :attr('data-nosnippet', '')
            :node(tabs)
            :done()
        :node(subTabs)
end
-- Main dynamic tabs function
function Tabs.dynamic(args)
    args = args or {}
    local tabArgs = readArguments(args, { removeEmptyTabs = readBool(args.removeEmptyTabs) })
    if #tabArgs == 0 then return nil end
    local hasContent = arrayAll(tabArgs, function(tab) return not isEmpty(tab.content) end)
    local allEmpty = arrayAll(tabArgs, function(tab) return isEmpty(tab.content) end)
    assert(hasContent or allEmpty, 'Some tabs have content while others do not')
    local isSingular = #tabArgs == 1 and hasContent
    if isSingular and not readBool(args.showSingularAsTab) then
        local header = nil
        if not readBool(args.suppressHeader) then
            header = mw.html.create('h6'):wikitext(tabArgs[1].name)
        end
        return mw.html.create()
            :node(header)
            :node(tabArgs[1].content)
    end
    local tabs = mw.html.create('ul')
        :addClass('nav nav-tabs tabs tabs' .. #tabArgs)
    if not arrayAny(tabArgs, property('this')) then
        tabArgs[1].this = true
     end
     end
 
      
    arrayForEach(tabArgs, function(tab, i)
     return container:node(tablist)
        tabs:tag('li')
            :addClass('tab' .. i)
            :addClass(tab.this and 'active' or nil)
            :wikitext(tab.name)
     end)
 
     if not readBool(args['hide-showall']) and not isSingular then
        tabs:tag('li')
            :addClass('show-all')
            :wikitext('Show All')
    end
 
    local contents = buildContentDiv(hasContent, readBool(args['hybrid-tabs']), readBool(args['no-padding']))
 
    if not hasContent then
        return mw.html.create('div')
            :addClass('tabs-dynamic navigation-not-searchable')
            :attr('data-nosnippet')
            :node(tabs)
            :node(contents)
    end
 
    arrayForEach(tabArgs, function(tab, i)
        contents:tag('div')
            :addClass('content' .. i)
            :addClass(tab.this and 'active' or nil)
            :node(tab.content)
    end)
 
    return mw.html.create('div')
        :addClass('tabs-dynamic navigation-not-searchable')
        :attr('data-nosnippet')
        :node(tabs)
        :node(contents)
end
end


return Tabs
return Tabs