Module:ElementHubNavigation: Difference between revisions

// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
Line 4: Line 4:
* Description: Hub navigation module for Main Page with zero-CLS responsive design
* Description: Hub navigation module for Main Page with zero-CLS responsive design
* Notes: Single SSR block with data-URI icons; mobile sticky bottom bar; desktop inline grid
* Notes: Single SSR block with data-URI icons; mobile sticky bottom bar; desktop inline grid
* Uses mw.html builder to prevent HTML escaping
* Uses MediaWiki table syntax + string concatenation (like ElementNavigation pattern)
]]
]]


Line 27: Line 27:
}
}


-- Generate a single hub link item using mw.html
-- Generate a single hub link item as HTML string
local function generateHubLink(hub)
local function generateHubLink(hub)
     local li = mw.html.create('li'):addClass('cdx-hub__item')
     return string.format(
   
        '<li class="cdx-hub__item"><a href="/wiki/%s" class="cdx-hub__link" data-hub="%s"><span class="cdx-hub__icon"><img src="%s" alt="" width="24" height="24" aria-hidden="true"></span><span class="cdx-hub__label">%s</span></a></li>',
    local a = li:tag('a')
        hub.url,
        :attr('href', '/wiki/' .. hub.url)
        hub.id,
        :addClass('cdx-hub__link')
         hub.icon,
        :attr('data-hub', hub.id)
         hub.label
   
     )
    -- Icon span with img
    local iconSpan = a:tag('span'):addClass('cdx-hub__icon')
    iconSpan:tag('img')
        :attr('src', hub.icon)
        :attr('alt', '')
        :attr('width', '24')
        :attr('height', '24')
        :attr('aria-hidden', 'true')
   
    -- Label span
    a:tag('span')
         :addClass('cdx-hub__label')
         :wikitext(hub.label)
   
     return tostring(li)
end
end


-- Main render function
-- Main render function
function p.render(frame)
function p.render(frame)
     -- Create main hub container
     -- Generate all hub links
     local container = mw.html.create('div')
     local hubLinks = {}
        :attr('id', 'hub')
     for i, hub in ipairs(hubs) do
        :addClass('cdx-hub')
         hubLinks[i] = generateHubLink(hub)
        :attr('role', 'navigation')
        :attr('aria-label', 'Hub Navigation')
   
    -- Create list
    local ul = container:tag('ul'):addClass('cdx-hub__list')
   
    -- Add hub links
     for _, hub in ipairs(hubs) do
         ul:wikitext(generateHubLink(hub))
     end
     end
      
      
     -- Add empty panel for future use
     -- Build complete output using MediaWiki table syntax + HTML
    container:tag('div')
        :addClass('cdx-hub__panel')
        :attr('aria-hidden', 'true')
   
    -- Create spacer
    local spacer = mw.html.create('div')
        :attr('id', 'hub-spacer')
        :attr('aria-hidden', 'true')
   
    -- Wrap in MediaWiki table syntax for compatibility
     local output = {
     local output = {
         '{| class="hub-nav-table"',
         '{| class="hub-nav-table"',
         '|- class="hub-nav-row"',
         '|- class="hub-nav-row"',
         '| colspan="2" |',
         '| colspan="2" |',
         tostring(container),
         '<div id="hub" class="cdx-hub" role="navigation" aria-label="Hub Navigation">',
         tostring(spacer),
        '  <ul class="cdx-hub__list">',
        '    ' .. table.concat(hubLinks, '\n    '),
         '  </ul>',
        '  <div class="cdx-hub__panel" aria-hidden="true"></div>',
        '</div>',
        '<div id="hub-spacer" aria-hidden="true"></div>',
         '|}'
         '|}'
     }
     }