Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Documentation

From Net 7 Portal Wiki

Module:Documentation/doc

From Wikipedia, see:
https://en.wikipedia.org/w/index.php?title=Module:Documentation
https://en.wikipedia.org/w/index.php?title=Template:Documentation

See related:

This module implements the template {{Meta/Documentation}}, see the documentation there.


The above doc is transcluded from Module:Documentation/doc. (edit | history)
Add categories to the /doc subpage, not here. Subpages of this template.


-- Get required modules.
local getArgs = require('Module:Arguments').getArgs

-- Get the config table.
local cfg = mw.loadData('Module:Documentation/config')

local p = {}

-- Often-used functions.
local ugsub = mw.ustring.gsub
local format = mw.ustring.format

----------------------------------------------------------------------------
-- Helper functions
--
-- These are defined as local functions, but are made available in the p
-- table for testing purposes.
----------------------------------------------------------------------------

local function message(cfgKey, valArray, expectType)
    --[[
    -- Gets a message from the cfg table and formats it if appropriate.
    -- The function raises an error if the value from the cfg table is not
    -- of the type expectType. The default type for expectType is 'string'.
    -- If the table valArray is present, strings such as $1, $2 etc. in the
    -- message are substituted with values from the table keys [1], [2] etc.
    -- For example, if the message "foo-message" had the value 'Foo $2 bar $1.',
    -- message('foo-message', {'baz', 'qux'}) would return "Foo qux bar baz."
    --]]
    local msg = cfg[cfgKey]
    expectType = expectType or 'string'
    if type(msg) ~= expectType then
        error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2)
    end
    if not valArray then
        return msg
    end

    local function getMessageVal(match)
        match = tonumber(match)
        return valArray[match] or error('message: no value found for key $' .. match .. ' in message cfg.' .. cfgKey, 4)
    end

    return ugsub(msg, '$([1-9][0-9]*)', getMessageVal)
end

p.message = message

local function makeWikilink(page, display)
    if display then
        return format('[[%s|%s]]', page, display)
    else
        return format('[[%s]]', page)
    end
end

p.makeWikilink = makeWikilink

local function makeCategoryLink(cat, sort)
    local catns = mw.site.namespaces[14].name
    return makeWikilink(catns .. ':' .. cat, sort)
end

p.makeCategoryLink = makeCategoryLink

local function makeUrlLink(url, display)
    return format('[%s %s]', url, display)
end

p.makeUrlLink = makeUrlLink

local function makeToolbar(...)
    local ret = {}
    local lim = select('#', ...)
    if lim < 1 then
        return nil
    end
    for i = 1, lim do
        ret[#ret + 1] = select(i, ...)
    end
    -- 'documentation-toolbar'
    return format(
        '<span class="%s">(%s)</span>',
        message('toolbar-class'),
        table.concat(ret, ' &#124; ')
    )
end    

p.makeToolbar = makeToolbar

----------------------------------------------------------------------------
-- Argument processing
----------------------------------------------------------------------------

local function makeInvokeFunc(funcName)
    return function (frame)
        local args = getArgs(frame, {
            valueFunc = function (key, value)
                if type(value) == 'string' then
                    value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
                    if key == 'heading' or value ~= '' then
                        return value
                    else
                        return nil
                    end
                else
                    return value
                end
            end
        })
        return p[funcName](args)
    end
end

----------------------------------------------------------------------------
-- Entry points
----------------------------------------------------------------------------

function p.nonexistent(frame)
    if mw.title.getCurrentTitle().subpageText == 'testcases' then
        return frame:expandTemplate{title = 'module test cases notice'}
    else
        return p.main(frame)
    end
end

p.main = makeInvokeFunc('_main')

function p._main(args)
    --[[
    -- This function defines logic flow for the module.
    -- @args - table of arguments passed by the user
    --]]
    local env = p.getEnvironment(args)
    local root = mw.html.create()
    root
        :wikitext(p._getModuleWikitext(args, env))
        -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
        --:wikitext(p.protectionTemplate(env))
        --:wikitext(p.sandboxNotice(args, env))
        :tag('div')
            -- 'documentation-container'
            :addClass(message('container'))
            :attr('role', 'complementary')
            :attr('aria-labelledby', args.heading ~= '' and 'documentation-heading' or nil)
            :attr('aria-label', args.heading == '' and 'Documentation' or nil)
            :newline()
            :tag('div')
                -- 'documentation'
                :addClass(message('main-div-classes'))
                :newline()
                :wikitext(p._startBox(args, env))
                :wikitext(p._content(args, env))
                :tag('div')
                    -- 'documentation-clear'
                    :addClass(message('clear'))
                    :done()
                :newline()
                :done()
            :wikitext(p._endBox(args, env))
            :done()
        :wikitext(p.addTrackingCategories(env))
    -- 'Module:Documentation/styles.css'
    return mw.getCurrentFrame():extensionTag('templatestyles', '', {src=cfg['templatestyles']}) .. tostring(root)
    --return tostring(root)
end

----------------------------------------------------------------------------
-- Environment settings
----------------------------------------------------------------------------

function p.getEnvironment(args)
    --[[
    -- Returns a table with information about the environment, including title
    -- objects and other namespace- or path-related data.
    -- @args - table of arguments passed by the user
    --
    -- Title objects include:
    -- env.title - the page we are making documentation for (usually the current title)
    -- env.templateTitle - the template (or module, file, etc.)
    -- env.docTitle - the /doc subpage.
    -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
    -- env.sandboxTitle - the /sandbox subpage.
    -- env.testcasesTitle - the /testcases subpage.
    --
    -- Data includes:
    -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
    -- env.protectionLevels - the protection levels table of the title object.
    --
    -- env.subjectSpace - the number of the title's subject namespace.
    -- env.docSpace - the number of the namespace the title puts its documentation in.
    -- env.docpageBase - the text of the base page of the /doc, /sandbox and /testcases pages, with namespace.
    -- env.compareUrl - URL of the Special:ComparePages page comparing the sandbox with the template.
    -- 
    -- All table lookups are passed through pcall so that errors are caught. If an error occurs, the value
    -- returned will be nil.
    --]]
    
    local env, envFuncs = {}, {}

    -- Set up the metatable. If triggered we call the corresponding function in the envFuncs table. The value
    -- returned by that function is memoized in the env table so that we don't call any of the functions
    -- more than once. (Nils won't be memoized.)
    setmetatable(env, {
        __index = function (t, key)
            local envFunc = envFuncs[key]
            if envFunc then
                local success, val = pcall(envFunc)
                if success then
                    env[key] = val -- Memoise the value.
                    return val
                end
            end
            return nil
        end
    })    

    function envFuncs.title()
        -- The title object for the current page, or a test page passed with args.page.
        local title
        local titleArg = args.page
        if titleArg then
            title = mw.title.new(titleArg)
        else
            title = mw.title.getCurrentTitle()
        end
        return title
    end

    function envFuncs.templateTitle()
        --[[
        -- The template (or module, etc.) title object.
        -- Messages:
        -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
        -- 'sandbox-subpage' --> 'sandbox'
        -- 'testcases-subpage' --> 'testcases'
        --]]
        local subjectSpace = env.subjectSpace
        local title = env.title
        local subpage = title.subpageText
        -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
        --if subpage == message('sandbox-subpage') or subpage == message('testcases-subpage') then
        --    return mw.title.makeTitle(subjectSpace, title.baseText)
        --else
            return mw.title.makeTitle(subjectSpace, title.text)
        --end
    end

    function envFuncs.docTitle()
        --[[
        -- Title object of the /doc subpage.
        -- Messages:
        -- 'doc-subpage' --> 'doc'
        --]]
        local title = env.title
        local docname = args[1] -- User-specified doc page.
        local docpage
        if docname then
            docpage = docname
        else
            docpage = env.docpageBase .. '/' .. message('doc-subpage')
        end
        return mw.title.new(docpage)
    end
    
    function envFuncs.subjectSpace()
        -- The subject namespace number.
        return mw.site.namespaces[env.title.namespace].subject.id
    end

    function envFuncs.docSpace()
        -- The documentation namespace number. For most namespaces this is the
        -- same as the subject namespace. However, pages in the Article, File,
        -- MediaWiki or Category namespaces must have their /doc, /sandbox and
        -- /testcases pages in talk space.
        local subjectSpace = env.subjectSpace
        if subjectSpace == 0 or subjectSpace == 6 or subjectSpace == 8 or subjectSpace == 14 then
            return subjectSpace + 1
        else
            return subjectSpace
        end
    end

    function envFuncs.docpageBase()
        -- The base page of the /doc, /sandbox, and /testcases subpages.
        -- For some namespaces this is the talk page, rather than the template page.
        local templateTitle = env.templateTitle
        local docSpace = env.docSpace
        local docSpaceText = mw.site.namespaces[docSpace].name
        -- Assemble the link. docSpace is never the main namespace, so we can hardcode the colon.
        return docSpaceText .. ':' .. templateTitle.text
    end
    
    function envFuncs.compareUrl()
        -- Diff link between the sandbox and the main template using [[Special:ComparePages]].
        local templateTitle = env.templateTitle
        -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
        --local sandboxTitle = env.sandboxTitle
        --if templateTitle.exists and sandboxTitle.exists then
        --    local compareUrl = mw.uri.canonicalUrl(
        --        'Special:ComparePages',
        --        { page1 = templateTitle.prefixedText, page2 = sandboxTitle.prefixedText}
        --    )
        --    return tostring(compareUrl)
        --else
            return nil
        --end
    end        

    return env
end    

----------------------------------------------------------------------------
-- Auxiliary templates
----------------------------------------------------------------------------

p.getModuleWikitext = makeInvokeFunc('_getModuleWikitext')

function p._getModuleWikitext(args, env)
    local currentTitle = mw.title.getCurrentTitle()
    if currentTitle.contentModel ~= 'Scribunto' then return end
    pcall(require, currentTitle.prefixedText) -- if it fails, we don't care
    local moduleWikitext =  package.loaded["Module:Wikitext"]
    if moduleWikitext then
        return moduleWikitext.main()
    end
end

----------------------------------------------------------------------------
-- Start box
----------------------------------------------------------------------------

p.startBox = makeInvokeFunc('_startBox')

function p._startBox(args, env)
    --[[
    -- This function generates the start box.
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- 
    -- The actual work is done by p.makeStartBoxLinksData and p.renderStartBoxLinks which make
    -- the [view] [edit] [history] [purge] links, and by p.makeStartBoxData and p.renderStartBox
    -- which generate the box HTML.
    --]]
    env = env or p.getEnvironment(args)
    local links
    local content = args.content
    if not content or args[1] then
        -- No need to include the links if the documentation is on the template page itself.
        local linksData = p.makeStartBoxLinksData(args, env)
        if linksData then
            links = p.renderStartBoxLinks(linksData)
        end
    end
    -- Generate the start box html.
    local data = p.makeStartBoxData(args, env, links)
    if data then
        return p.renderStartBox(data)
    else
        -- User specified no heading.
        return nil
    end
end

function p.makeStartBoxLinksData(args, env)
    --[[
    -- Does initial processing of data to make the [view] [edit] [history] [purge] links.
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- 
    -- Messages:
    -- 'view-link-display' --> 'view'
    -- 'edit-link-display' --> 'edit'
    -- 'history-link-display' --> 'history'
    -- 'purge-link-display' --> 'purge'
    -- 'module-preload' --> See Module:Documentation/config
    -- 'docpage-preload' --> See Module:Documentation/config
    -- 'create-link-display' --> 'create'
    --]]
    local subjectSpace = env.subjectSpace
    local title = env.title
    local docTitle = env.docTitle
    if not title or not docTitle then
        return nil
    end
    if docTitle.isRedirect then 
        docTitle = docTitle.redirectTarget
    end

    -- Create link if /doc doesn't exist.
    local preload = args.preload
    if not preload then
        if subjectSpace == 828 then -- Module namespace
            preload = message('module-preload')
            -- Codemonkeyx:
            docTitle = title
        else
            preload = message('docpage-preload')
        end
    end
    
    return {
        title = title,
        docTitle = docTitle,
        -- View, display, edit, and purge links if /doc exists.
        viewLinkDisplay = message('view-link-display'),
        editLinkDisplay = message('edit-link-display'),
        historyLinkDisplay = message('history-link-display'),
        purgeLinkDisplay = message('purge-link-display'),
        preload = preload,
        createLinkDisplay = message('create-link-display')
    }
end

function p.renderStartBoxLinks(data)
    --[[
    -- Generates the [view][edit][history][purge] or [create][purge] links from the data table.
    -- @data - a table of data generated by p.makeStartBoxLinksData
    --]]
    local docTitle = data.docTitle
    -- yes, we do intend to purge the template page on which the documentation appears
    local purgeLink = makeWikilink("Special:Purge/" .. data.title.prefixedText, data.purgeLinkDisplay)
    
    if docTitle.exists then
        local viewLink = makeWikilink(docTitle.prefixedText, data.viewLinkDisplay)
        local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, data.editLinkDisplay)
        local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, data.historyLinkDisplay)
        return "&#91;" .. viewLink .. "&#93; &#91;" .. editLink .. "&#93; &#91;" .. historyLink .. "&#93; &#91;" .. purgeLink .. "&#93;"
    else
        local createLink = makeUrlLink(docTitle:canonicalUrl{action = 'edit', preload = data.preload}, data.createLinkDisplay)
        return  "&#91;" .. createLink .. "&#93; &#91;" .. purgeLink .. "&#93;"
    end
    return ret
end

function p.makeStartBoxData(args, env, links)
    --[=[
    -- Does initial processing of data to pass to the start-box render function, p.renderStartBox.
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- @links - a string containing the [view][edit][history][purge] links - could be nil if there's an error.
    --
    -- Messages:
    -- 'documentation-icon-wikitext' --> See Module:Documentation/config
    -- 'template-namespace-heading' --> See Module:Documentation/config
    -- 'module-namespace-heading' --> See Module:Documentation/config
    -- 'file-namespace-heading' --> 'Summary'
    -- 'other-namespaces-heading' --> See Module:Documentation/config
    -- 'testcases-create-link-display' --> 'create'
    --]=]
    local subjectSpace = env.subjectSpace
    if not subjectSpace then
        -- Default to an "other namespaces" namespace, so that we get at least some output
        -- if an error occurs.
        subjectSpace = 2
    end
    local data = {}
    
    -- Heading
    local heading = args.heading -- Blank values are not removed.
    if heading == '' then
        -- Don't display the start box if the heading arg is defined but blank.
        return nil
    end
    if heading then
        data.heading = heading
    elseif subjectSpace == 10 then -- Template namespace
        data.heading = message('documentation-icon-wikitext') .. ' ' .. message('template-namespace-heading')
    elseif subjectSpace == 828 then -- Module namespace
        data.heading = message('documentation-icon-wikitext') .. ' ' .. message('module-namespace-heading')
    elseif subjectSpace == 6 then -- File namespace
        data.heading = message('file-namespace-heading')
    else
        data.heading = message('other-namespaces-heading')
    end
    
    -- Heading CSS
    local headingStyle = args['heading-style']
    if headingStyle then
        data.headingStyleText = headingStyle
    else
        -- 'documentation-heading'
        data.headingClass = message('main-div-heading-class')
    end
    
    -- Data for the [view][edit][history][purge] or [create] links.
    if links then
        -- 'mw-editsection-like plainlinks'
        data.linksClass = message('start-box-link-classes')
        data.links = links
    end
    
    return data
end

function p.renderStartBox(data)
    -- Renders the start box html.
    -- @data - a table of data generated by p.makeStartBoxData.
    local sbox = mw.html.create('div')
    sbox
        -- 'documentation-startbox'
        :addClass(message('start-box-class'))
        :newline()
        :tag('span')
            :addClass(data.headingClass)
            :attr('id', 'documentation-heading')
            :cssText(data.headingStyleText)
            :wikitext(data.heading)
    local links = data.links
    if links then
        sbox:tag('span')
            :addClass(data.linksClass)
            :attr('id', data.linksId)
            :wikitext(links)
    end
    return tostring(sbox)
end

----------------------------------------------------------------------------
-- Documentation content
----------------------------------------------------------------------------

p.content = makeInvokeFunc('_content')

function p._content(args, env)
    -- Displays the documentation contents
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    env = env or p.getEnvironment(args)
    local docTitle = env.docTitle
    local content = args.content
    if not content and docTitle and docTitle.exists then
        content = args._content or mw.getCurrentFrame():expandTemplate{title = docTitle.prefixedText}
    end
    -- The line breaks below are necessary so that "=== Headings ===" at the start and end
    -- of docs are interpreted correctly.
    return '\n' .. (content or '') .. '\n' 
end

p.contentTitle = makeInvokeFunc('_contentTitle')

function p._contentTitle(args, env)
    env = env or p.getEnvironment(args)
    local docTitle = env.docTitle
    if not args.content and docTitle and docTitle.exists then
        return docTitle.prefixedText
    else
        return ''
    end
end

----------------------------------------------------------------------------
-- End box
----------------------------------------------------------------------------

p.endBox = makeInvokeFunc('_endBox')

function p._endBox(args, env)
    --[=[
    -- This function generates the end box (also known as the link box).
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- 
    --]=]
    
    -- Get environment data.
    env = env or p.getEnvironment(args)
    local subjectSpace = env.subjectSpace
    local docTitle = env.docTitle
    if not subjectSpace or not docTitle then
        return nil
    end
        
    -- Check whether we should output the end box at all. Add the end
    -- box by default if the documentation exists or if we are in the
    -- user, module or template namespaces.
    local linkBox = args['link box']
    if linkBox == 'off'
        or not (
            docTitle.exists
            or subjectSpace == 2
            or subjectSpace == 828
            or subjectSpace == 10
        )
    then
        return nil
    end

    -- Assemble the link box.
    local text = ''
    if linkBox then
        text = text .. linkBox
    else
        text = text .. (p.makeDocPageBlurb(args, env) or '') -- 'transcluded-from-blurb', See Module:Documentation/config
        if subjectSpace == 2 or subjectSpace == 10 or subjectSpace == 828 then
            -- We are in the user, template or module namespaces.

            -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
            -- Add sandbox and testcases links.
            -- "Editors can experiment in this template's sandbox and testcases pages."
            --text = text .. (p.makeExperimentBlurb(args, env) or '') .. '<br />'
            if not args.content and not args[1] then
                -- 'add-categories-blurb' --> See Module:Documentation/config
                -- Don't show this message with inline docs or with an explicitly specified doc page,
                -- as then it is unclear where to add the categories.
                text = text .. (p.makeCategoriesBlurb(args, env) or '')
            end
            text = text .. ' ' .. (p.makeSubpagesBlurb(args, env) or '') --"Subpages of this template"
        end
    end
    
    local box = mw.html.create('div')
    -- 'documentation-metadata'
    box:attr('role', 'note')
        :addClass(message('end-box-class'))
        -- 'plainlinks'
        :addClass(message('end-box-plainlinks'))
        :wikitext(text)
        :done()

    return '\n' .. tostring(box)
end

function p.makeDocPageBlurb(args, env)
    --[=[
    -- Makes the blurb 'transcluded-from-blurb', See Module:Documentation/config
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- 
    -- Messages:
    -- 'edit-link-display' --> 'edit'
    -- 'history-link-display' --> 'history'
    -- 'transcluded-from-blurb' --> See Module:Documentation/config
    -- 'module-preload' --> See Module:Documentation/config
    -- 'create-link-display' --> 'create'
    -- 'create-module-doc-blurb' --> See Module:Documentation/config
    --]=]
    local docTitle = env.docTitle
    if not docTitle then
        return nil
    end
    local ret
    if docTitle.exists then
        -- /doc exists; link to it.
        local docLink = makeWikilink(docTitle.prefixedText)
        local editDisplay = message('edit-link-display')
        local editLink = makeWikilink("Special:EditPage/" .. docTitle.prefixedText, editDisplay)
        local historyDisplay = message('history-link-display')
        local historyLink = makeWikilink("Special:PageHistory/" .. docTitle.prefixedText, historyDisplay)
        ret = message('transcluded-from-blurb', {docLink})
            .. ' '
            .. makeToolbar(editLink, historyLink)
            .. '<br />'
    elseif env.subjectSpace == 828 then
        -- Codemonkeyx:
        -- For Modules the only way to get this preload seems to be to create
        -- the /doc page yourself, paste {{subst:doc}}, then get this "create"
        -- link which is really just editing the current page and replacing
        -- the contents with module-preload
        local moduleDocTitle = env.title
        if not moduleDocTitle then
            return nil
        end
        local createUrl = moduleDocTitle:canonicalUrl{action = 'edit', section = 'new', preload = message('module-preload')}
        local createDisplay = message('create-link-display')
        local createLink = makeUrlLink(createUrl, createDisplay)
        ret = message('create-module-doc-blurb', {createLink})
            .. '<br />'
    end
    return ret
end

function p.makeCategoriesBlurb(args, env)
    --[[
    -- Generates the text 'add-categories-blurb' --> See Module:Documentation/config
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    -- Messages:
    -- 'doc-link-display' --> '/doc'
    -- 'add-categories-blurb' --> See Module:Documentation/config
    --]]
    local docTitle = env.docTitle
    if not docTitle then
        return nil
    end
    local docPathLink = makeWikilink(docTitle.prefixedText, message('doc-link-display'))
    return message('add-categories-blurb', {docPathLink})
end

function p.makeSubpagesBlurb(args, env)
    --[[
    -- Generates the "Subpages of this template" link.
    -- @args - a table of arguments passed by the user
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    
    -- Messages:
    -- 'template-pagetype' --> 'template'
    -- 'module-pagetype' --> 'module'
    -- 'default-pagetype' --> 'page'
    -- 'subpages-link-display' --> 'Subpages of this $1'
    --]]
    local subjectSpace = env.subjectSpace
    local templateTitle = env.templateTitle
    if not subjectSpace or not templateTitle then
        return nil
    end
    local pagetype
    if subjectSpace == 10 then
        pagetype = message('template-pagetype')
    elseif subjectSpace == 828 then
        pagetype = message('module-pagetype')
    else
        pagetype = message('default-pagetype')
    end
    local subpagesLink = makeWikilink(
        'Special:PrefixIndex/' .. templateTitle.prefixedText .. '/',
        message('subpages-link-display', {pagetype})
    )
    return message('subpages-blurb', {subpagesLink})
end

----------------------------------------------------------------------------
-- Tracking categories
----------------------------------------------------------------------------

function p.addTrackingCategories(env)
    --[[
    -- Check if {{Meta/Documentation}} is transcluded on a /doc or /testcases page.
    -- @env - environment table containing title objects, etc., generated with p.getEnvironment
    
    -- Messages:
    -- 'display-strange-usage-category' --> true
    -- 'doc-subpage' --> 'doc'
    -- 'testcases-subpage' --> 'testcases'
    -- 'strange-usage-category' --> See Module:Documentation/config
    --]]
    local title = env.title
    local subjectSpace = env.subjectSpace
    if not title or not subjectSpace then
        return nil
    end
    local subpage = title.subpageText
    local ret = ''
    if message('display-strange-usage-category', nil, 'boolean')
        and (
            subpage == message('doc-subpage')
            -- Codemonkeyx: removed along with related functions for simplified Net-7 usage
            --or subjectSpace ~= 828 and subpage == message('testcases-subpage')
        )
    then
        ret = ret .. makeCategoryLink(message('strange-usage-category'))
    end
    return ret
end

return p