Module:Portal bar: Difference between revisions
turn mobile on, turn off media viewer |
factor duplicate code out into Module:Portal |
||
Line 3: | Line 3: | ||
require('Module:No globals') |
require('Module:No globals') |
||
local |
local portalModule = require('Module:Portal') |
||
local getImageName = portalModule.image |
|||
local checkTracking = portalModule._checkTracking |
|||
local processPortalArgs = portalModule._processPortalArgs |
|||
local yesno = require( 'Module:Yesno' ) |
local yesno = require( 'Module:Yesno' ) |
||
local getArgs = require('Module:Arguments').getArgs |
local getArgs = require('Module:Arguments').getArgs |
||
Line 10: | Line 13: | ||
local function sandbox(args, s) |
local function sandbox(args, s) |
||
return args.sandbox and s.."-sand" or s |
return args.sandbox and s.."-sand" or s |
||
⚫ | |||
-- 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 |
end |
||
Line 44: | Line 19: | ||
-- Don't display a blank navbox if no portals were specified. |
-- Don't display a blank navbox if no portals were specified. |
||
if #portals < 1 then return '' end |
if (not portals) or (#portals < 1) then return '' end |
||
-- check for sensible args |
|||
args = type(args) == "table" and args or {} |
|||
-- Normalize arguments |
-- Normalize arguments |
||
for key, default in pairs({border=true,redlinks=false,sandbox=false,tracking=true}) do |
|||
⚫ | |||
if args[key] == nil then args[key] = default end |
|||
⚫ | |||
⚫ | |||
local nav = mw.html.create( 'div' ) |
local nav = mw.html.create( 'div' ) |
||
Line 55: | Line 35: | ||
:attr( 'role', 'navigation' ) |
:attr( 'role', 'navigation' ) |
||
:attr( 'aria-label' , 'Portals' ) |
:attr( 'aria-label' , 'Portals' ) |
||
⚫ | |||
if yesno( args.border ) == false then |
|||
nav |
|||
⚫ | |||
else |
|||
nav |
|||
:addClass(sandbox(args,'portal-bar-bordered')) |
|||
end |
|||
local trackingEnabled = |
local trackingEnabled = args.tracking and checkTracking() |
||
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 |
-- scan for nonexistent portals, if they exist remove them from the portals |
||
-- table. If redlinks=yes, then don't remove |
-- table. If redlinks=yes, then don't remove |
||
local trackingCats = '' |
local trackingCats = '' |
||
if not args.redlinks then |
if not args.redlinks or trackingEnabled then |
||
local existingPortals = {} |
local existingPortals = {} |
||
for _, portal in ipairs(portals) do |
for _, portal in ipairs(portals) do |
||
Line 83: | Line 52: | ||
end |
end |
||
end |
end |
||
⚫ | |||
if # |
if #portals == 0 then |
||
return trackingEnabled and "[[Category:Portal templates with all redlinked portals]]" or "" |
return trackingEnabled and "[[Category:Portal templates with all redlinked portals]]" or "" |
||
end |
end |
||
⚫ | |||
end |
end |
||
Line 124: | Line 93: | ||
function p.main( frame ) |
function p.main( frame ) |
||
local origArgs = getArgs(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. |
|||
⚫ | |||
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 ) |
return p._main( portals, args ) |
||
end |
end |
Revision as of 23:27, 22 December 2021
![]() | 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 portalModule = require('Module:Portal')
local getImageName = portalModule.image
local checkTracking = portalModule._checkTracking
local processPortalArgs = portalModule._processPortalArgs
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
-- 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 (not portals) or (#portals < 1) then return '' end
-- check for sensible args
args = type(args) == "table" and args or {}
-- Normalize arguments
for key, default in pairs({border=true,redlinks=false,sandbox=false,tracking=true}) do
if args[key] == nil then args[key] = default end
args[key] = yesno(args[key], default)
end
local nav = mw.html.create( 'div' )
:addClass(sandbox(args,'portal-bar'))
:addClass( 'noprint metadata noviewer' )
:attr( 'role', 'navigation' )
:attr( 'aria-label' , 'Portals' )
:addClass(sandbox(args,args.border and 'portal-bar-bordered' or 'portal-bar-unbordered'))
local trackingEnabled = args.tracking and checkTracking()
-- 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 or trackingEnabled 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
portals = args.redlinks and portals or existingPortals
if #portals == 0 then
return trackingEnabled and "[[Category:Portal templates with all redlinked portals]]" or ""
end
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)
local portals, args = processPortalArgs(origArgs)
return p._main( portals, args )
end
return p