Module:Portal
Documentation for this module may be created at Module:Portal/doc
-- This module implements {{Portal}}
local p = {}
local HtmlBuilder = require('Module:HtmlBuilder')
local HtmlError = require('Module:Error')
-- This function generates the html code.
local function _portal(args)
local root = HtmlBuilder.create('div')
root
.addClass('noprint')
.addClass((args.left == 'yes' and 'tleft') or 'tright')
.addClass('portal')
.css('border', 'solid #aaa 1px')
.css('margin', args.margin or (args.left == 'yes' and '0.5em 1em 0.5em 0') or '0.5em 0 0.5em 1em')
.newline()
-- Start the table. This corresponds to the start of the wikitext table
-- in the old [[Template:Portal]].
local tableroot = root.tag('table')
.css('background', '#f9f9f9')
.css('font-size', '85%')
.css('line-height', '110%')
.css('max-width', '175px')
.css('width', args.boxsize and (args.boxsize .. 'px'))
-- If no portals have been specified, display an error and add the page to a tracking category.
if not args[1] then
tableroot.wikitext(
tostring(HtmlError.error{'No portals specified: please specify at least one portal'})
.. '[[Category:Portal templates without a parameter]]'
)
end
-- Display the portals specified in the positional arguments.
for i,v in ipairs(args) do
v = mw.ustring.match(v, '^%s*(.*%S)') or '' -- Trim whitespace.
-- Portal image names are stored in subtemplates of [[Template:Portal/Images]].
-- The name of the subtemplate is the portal name in all lower case, but with
-- the first character in upper case.
-- Work out the image subtemplate location.
local lang = mw.getContentLanguage()
local imagetemplatename = 'Portal/Images/' .. lang:ucfirst(lang:lc(v))
-- Check the image template name. We need three checks: 1) check with pcall to see if
-- we are over the expensive function call limit; 2) check if the proposed image template
-- name uses invalid characters (mw.title.new returns nil if this is the case); and 3)
-- check if the image subtemplate exists.
local goodtitlecall, imagetemplateobject = pcall(mw.title.new, imagetemplatename, 'Template')
if not (goodtitlecall and imagetemplateobject and imagetemplateobject.exists) then
imagetemplatename = 'Portal/Images/Default'
end
-- Expand the image subtemplate to get the image name
local imagename = mw.getCurrentFrame():expandTemplate{ title = imagetemplatename }
-- Generate the html for the image and the portal name.
tableroot
.newline()
.tag('tr')
.attr('valign', 'middle')
.tag('td')
.css('text-align', 'center')
.wikitext('[[File:' .. imagename .. '|32x28px|alt=Portal icon]]')
.done()
.tag('td')
.css('padding', '0 0.2em')
.css('vertical-align', 'middle')
.css('font-style', 'italic')
.css('font-weight', 'bold')
.wikitext('[[Portal:' .. v .. '|' .. v .. ((args['break'] == 'yes' and '<br />') or ' ') .. 'portal]]')
end
return tostring(root)
end
-- This function gets the arguments passed to the module and passes them
-- to the _portal() function above.
function p.portal(frame)
local orig_args
if frame == mw.getCurrentFrame() then
-- We're being called via #invoke. If the invoking template passed any arguments,
-- use them. Otherwise, use the arguments that were passed into the template.
orig_args = frame:getParent().args
for k, v in pairs(frame.args) do
orig_args = frame.args
break
end
else
-- We're being called from another module or from the debug console, so assume
-- the arguments are passed in directly.
orig_args = frame
end
-- We want to list all the portals in the order they were passed to the template.
-- We also want to be able to deal with positional arguments passed explicitly,
-- for example {{portal|2=Politics}}. However, pairs() doesn't guarantee the correct
-- order, and ipairs() will stop after the first nil value. To get around this, we
-- create a new table of arguments where nil values have been removed, so that we
-- can traverse the numerical arguments using ipairs(). We also remove values which
-- only consist of whitespace. ParserFunctions considers these to be false, and by
-- removing them Lua will consider them false too.
local args = {} -- Arguments table.
local name_args = {} -- Temporary table for named arguments.
for k, v in pairs(orig_args) do
if mw.ustring.match(v, '%S') then -- Remove values that are only whitespace.
if type(k) == 'number' then
table.insert(args, k) -- Put positional argument keys into the arguments table so we can sort them.
else
-- Put named argument values in their own table while we sort the positional arguments,
-- so that we don't have to cycle through all the original arguments again.
name_args[k] = v
end
end
end
table.sort(args) -- Sort the positional argument keys into numerical order.
for i,v in ipairs(args) do
args[i] = orig_args[v] -- Replace positional argument keys with their corresponding values.
end
for k,v in pairs(name_args) do
args[k] = v -- Add named arguments to the args table
end
return _portal(args)
end
return p