Module:Portal bar
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This Lua module is used on approximately 173,000 pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
![]() | This module depends on the following other modules: |
![]() | This module uses TemplateStyles: |
This module implements the {{portal bar}} template. It displays a horizontal bar of portals.
See here and here for testcases.
Note: in order to make the test cases work, the Sandbox CSS classes have "-sand" appended to their names. If you wish to update the CSS, copy the contents of each class from Module:Portal bar/sandbox/styles.css to Module:Portal bar/styles.css, but do not alter the class names, nor just copy-paste the entire CSS file. For the current difference in CSS between Sandbox and Main, see here.
Usage
{{#invoke:Portal bar|main|''portal 1''|''portal 2 ''|...|border=''no''}}
- Positional parameters - the names of the portals to be displayed.
border
- if|border=
is equal tono
,n
,false
, or0
, then the portal box will have no border.redlinks
- if|redlinks=
is equal toyes
,y
,true
orinclude
, then the portal box will show redlinked portals
Examples
{{#invoke:portal bar|main|Visual arts|Science|Literature}}
Produces:
Lua error in package.lua at line 80: module 'Module:No globals' not found.
{{#invoke:portal bar|main|Visual arts|Science|Literature|border=no}}
Produces:
Lua error in package.lua at line 80: module 'Module:No globals' not found.
For further examples, see Template:Portal bar/testcases.
Images
This module uses Module:Portal to get portal images. To add, change, or remove images, please see the instructions at Module:Portal#Image.
-- This module implements {{portal bar}}.
require('Module:No globals')
local getImageName = require( 'Module:Portal' ).image
local yesno = require( 'Module:Yesno' )
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function sandbox(args, s)
return args.sandbox and s.."-sand" or s
end
-- Check whether to do tracking in this namespace
-- Returns true unless the page is one of the banned namespaces
local function isTrackedNamespace()
local thisPageNS = mw.title.getCurrentTitle().namespace
return thisPageNS ~= 1 -- Talk
and thisPageNS ~= 2 -- User
and thisPageNS ~= 3 -- User talk
and thisPageNS ~= 5 -- Wikipedia talk
and thisPageNS ~= 7 -- File talk
and thisPageNS ~= 11 -- Template talk
and thisPageNS ~= 15 -- Category talk
and thisPageNS ~= 101 -- Portal talk
and thisPageNS ~= 118 -- Draft
and thisPageNS ~= 119 -- Draft talk
and thisPageNS ~= 829 -- Module talk
end
-- Check whether to do tracking on this pagename
-- Returns false if the page title matches one of the banned strings
-- Otherwise returns true
local function isTrackedPagename()
local thisPageLC = mw.ustring.lower(mw.title.getCurrentTitle().text)
local match = string.match
return match(thisPageLC, "/archive") == nil
and match(thisPageLC, "/doc") == nil
and match(thisPageLC, "/test") == nil
end
-- Builds the portal bar used by {{portal bar}}.
function p._main( portals, args )
-- Don't display a blank navbox if no portals were specified.
if #portals < 1 then return '' end
-- Normalize arguments
args.sandbox = yesno(args.sandbox)
args.redlinks = yesno(args.redlinks)
local nav = mw.html.create( 'div' )
:addClass(sandbox(args,'portal-bar'))
:addClass( 'noprint metadata nomobile' )
:attr( 'role', 'navigation' )
:attr( 'aria-label' , 'Portals' )
if yesno( args.border ) == false then
nav
:addClass(sandbox(args,'portal-bar-unbordered'))
else
nav
:addClass(sandbox(args,'portal-bar-bordered'))
end
local trackingEnabled = true
local tracking = args.tracking
if (tracking == 'no' or tracking == 'n' or tracking == 'false') or
not isTrackedNamespace() or not isTrackedPagename() then
trackingEnabled = false
end
-- scan for nonexistent portals, if they exist remove them from the portals
-- table. If redlinks=yes, then don't remove
local trackingCats = ''
if not args.redlinks then
local existingPortals = {}
for _, portal in ipairs(portals) do
local portalTitle = mw.title.new(portal,"Portal")
if portalTitle and portalTitle.exists then
table.insert(existingPortals,portal)
elseif trackingEnabled then
trackingCats = "[[Category:Portal templates with redlinked portals]]"
end
end
if #existingPortals == 0 then
return trackingEnabled and "[[Category:Portal templates with all redlinked portals]]" or ""
end
portals = existingPortals
end
local header = nav:tag('span')
header:addClass(sandbox(args,'portal-bar-header'))
header:wikitext('[[Wikipedia:Contents/Portals|Portal]]')
if #portals > 1 then
header:wikitext('s')
end
header:wikitext(':')
local container = nav:tag('div')
container:addClass(sandbox(args,'portal-bar-content'))
for _, portal in ipairs( portals ) do
container
:tag( 'div' )
:addClass(sandbox(args,'portal-bar-item'))
:tag( 'span' )
:addClass(sandbox(args,'portal-bar-logo'))
:wikitext( string.format(
'[[File:%s|21x19px|alt=]]', getImageName{ portal }
) )
:done()
:tag('span')
:addClass(sandbox(args,'portal-bar-link'))
:wikitext( string.format('[[Portal:%s|%s]]', portal, portal))
end
local styleFile = 'Module:Portal bar/'
styleFile = styleFile..(args.sandbox and 'sandbox/' or '')
styleFile = styleFile..'styles.css'
return mw.getCurrentFrame():extensionTag{
name = 'templatestyles', args = { src = styleFile }
} .. tostring( nav ) .. trackingCats
end
-- Processes external arguments and sends them to the other functions.
function p.main( frame )
local origArgs = getArgs(frame)
-- Process the args to make an array of portal names that can be used with
-- ipairs. We need to use ipairs because we want to list all the portals in
-- the order they were passed to the template, but we also want to be able
-- to deal with positional arguments passed explicitly, for example
-- {{portal|2=Politics}}. The behaviour of ipairs is undefined if nil values
-- are present, so we need to make sure they are all removed.
local portals, args = {}, {}
for k, v in pairs( origArgs ) do
-- Make sure we have no non-string portal names.
if type( k ) == 'number' and type( v ) == 'string' then
table.insert(portals, k)
elseif type( k ) ~= 'number' then -- Separate named arguments from portals.
args[ k ] = v
end
end
table.sort( portals )
for i, v in ipairs( portals ) do
-- Swap keys with values
portals[ i ] = origArgs[ v ]
end
return p._main( portals, args )
end
return p