Powers Wiki
Explore
Main Page
Discuss
All Pages
Community
Interactive Maps
Recent Blog Posts
Powers
Recently Changed Pages
Big Bad Wolfe/TV
Simons
SuperShock/TV
Jumpstriker
Powers (comics)
Zora
Zora/TV
Seasons
Powers (TV series)
Season 1
Season 1
Season 2
Season 2
Characters
Christian Walker
Deena Pilgrim/TV
Johnny Royalle/TV
Retro Girl/TV
Captain Cross/TV
Zora/TV
Triphammer/TV
"Powers"
Powers Division
Deena Pilgrim/TV
Captain Cross/TV
Christian Walker/TV
Cast
Sharlto Copley
Susan Heyward
Community
Recent blog posts
Forum
FANDOM
Fan Central
BETA
Games
Anime
Movies
TV
Video
Wikis
Explore Wikis
Community Central
Start a Wiki
Don't have an account?
Register
Sign In
Sign In
Register
Powers Wiki
83
pages
Explore
Main Page
Discuss
All Pages
Community
Interactive Maps
Recent Blog Posts
Powers
Recently Changed Pages
Big Bad Wolfe/TV
Simons
SuperShock/TV
Jumpstriker
Powers (comics)
Zora
Zora/TV
Seasons
Powers (TV series)
Season 1
Season 1
Season 2
Season 2
Characters
Christian Walker
Deena Pilgrim/TV
Johnny Royalle/TV
Retro Girl/TV
Captain Cross/TV
Zora/TV
Triphammer/TV
"Powers"
Powers Division
Deena Pilgrim/TV
Captain Cross/TV
Christian Walker/TV
Cast
Sharlto Copley
Susan Heyward
Community
Recent blog posts
Forum
Editing
Module:Tabs
Back to page
Edit source
View history
Talk (0)
Edit Page
Module:Tabs
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- <nowiki> ------------------------------------------------------------------------------- -- Module:Tabs -- -- This module renders the icons in the top-right corner of articles, as well -- as the Comics and TV tabs for pages with a Comics/TV counterpart. -- It also formats the page title with {{DISPLAYTITLE}}. It is a rewrite of -- [[Template:Tabs]]. ------------------------------------------------------------------------------- local DEBUG_MODE = false -- if true, errors are not caught ------------------------------------------------------------------------------- -- Icon data ------------------------------------------------------------------------------- --[[ -- This table stores data for all the icons displayed in the top-right. It can -- have the following fields: -- * image - the icon image name, minus any "File:" prefix (required). -- * tooltip - the icon tooltip (optional). -- * link - the page to link from the icon (optional). -- * category - a category to go with the icon, minus any "Category:" prefix -- (optional). -- * protectionAction - for protection icons, an action such as "edit" or "move" -- to check (optional). -- * protectionLevel - for protection icons, the protection level to check, -- such as "sysop". If the page doesn't have the right protection level -- it is put in a tracking category and the icon is not displayed -- (optional). -- Note: this is just a convenient place to store the data. The subtables are -- accessed from the code manually, so adding new subtables won't automatically -- add new icons, and removing subtables may break things. --]] local iconData = { pre = { image = "30px-Era-pre.png", tooltip = "The subject of this article appeared before the Before the Republic era.", link = "Pre-Republic era" }, btr = { image = "30px-Era-pre2.png", tooltip = "The subject of this article appeared Before the Republic.", link = "Before the Republic" }, old = { image = "30px-Era-old.png", tooltip = "The subject of this article appeared in the Old Republic era.", link = "Old Republic era" }, imp = { image = "30px-Era-imp.png", tooltip = "The subject of this article appeared in the Rise of the Empire era.", link = "Rise of the Empire era" }, reb = { image = "30px-Era-reb.png", tooltip = "The subject of this article appeared in the Rebellion era.", link = "Rebellion era" }, new = { image = "30px-Era-new.png", tooltip = "The subject of this article appeared in the New Republic era.", link = "New Republic era" }, njo = { image = "30px-Era-njo.png", tooltip = "The subject of this article appeared in the New Jedi Order era.", link = "New Jedi Order era" }, leg = { image = "30px-Era-leg.png", tooltip = "The subject of this article appeared in the Legacy era.", link = "Legacy era" }, inf = { image = "30px-Era-inf.png", tooltip = "The subject of this article is considered part of Star Wars Infinities.", link = "Infinities" }, real = { image = "30px-Era-real.png", tooltip = "The subject of this article exists in or is relevant to the real world.", link = "Category:Real-world articles" }, featured = { image = "30px-FeaturedIcon.png", tooltip = "This is a Wookieepedia Featured Article.", link = "Wookieepedia:Featured articles", category = "Wookieepedia featured articles" }, former = { image = "30px-DefeaturedIcon.png", tooltip = "This is a former Wookieepedia Featured Article.", link = "Wookieepedia:Featured articles", category = "Wookieepedia former featured articles" }, good = { image = "30px-GoodIcon.png", tooltip = "This is a Wookieepedia Good Article.", link = "Wookieepedia:Good articles", category = "Wookieepedia good articles" }, fga = { image = "30px-FormerGAicon.png", tooltip = "This is a former Wookieepedia Good Article.", link = "Wookieepedia:Good articles", category = "Wookieepedia former good articles" }, comp = { image = "30px-ComprehensiveArticle.png", tooltip = "This is a Wookieepedia Comprehensive Article.", link = "Wookieepedia:Comprehensive articles", category = "Wookieepedia comprehensive articles" }, fca = { image = "30px-FormerCAIcon.png", tooltip = "This is a former Wookieepedia Comprehensive Article.", link = "Wookieepedia:Comprehensive articles", category = "Wookieepedia former comprehensive articles" }, fprot = { protectionAction = "edit", protectionLevel = "sysop", image = "30px-Era-Fprotect.png", tooltip = "This article is protected from editing.", link = "Wookieepedia:Protection_policy#Full_protection", category = "Protected" }, sprot = { protectionAction = "edit", protectionLevel = "autoconfirmed", image = "30px-Era-Sprotect.png", tooltip = "This article is semi-protected.", link = "Wookieepedia:Protection_policy#Semi-protection", category = "Semi-protected articles" }, ssprot = { image = "30px-Era-Ssprotect.png", tooltip = "This article is super-semi-protected.", link = "Wookieepedia:Protection_policy#Super-semi-protection", category = "Super-semi-protected articles" }, mprot = { protectionAction = "move", protectionLevel = "sysop", image = "30px-Era-Mprotect.png", tooltip = "This article is move protected.", link = "Wookieepedia:Protection_policy#Move protection", category = "Move protected articles" }, uprot = { protectionAction = "upload", protectionLevel = "sysop", image = "30px-Era-Uprotect.png", tooltip = "This file is upload protected.", link = "Wookieepedia:Protection_policy#Upload protection", category = "Upload protected files" }, noncanon = { image = "30px-Era-inf.png", tooltip = "The subject of this article is considered non-canon." } } ------------------------------------------------------------------------------- -- Helper functions ------------------------------------------------------------------------------- -- Find whether the specified page exists. We use pcall to catch errors if we -- are over the expensive parser function count limit, or a number of other -- juicy errors. This function increases the expensive parser function count -- for every new page called. local function exists(page) local success, title = pcall(mw.title.new, page) return success and title and title.exists or false end ------------------------------------------------------------------------------- -- Tabs class ------------------------------------------------------------------------------- -- The tabs class does all of the heavy lifting in the module. We use a class -- rather than normal functions so that we can avoid passing lots of different -- values around for each different function. local Tabs = {} Tabs.__index = Tabs -- Set up inheritance for tables that use Tabs as a metatable. -- This function makes a new tabs object. Here we set all the values from the -- arguments and do any preprocessing that we need. function Tabs.new(args, title) local obj = setmetatable({}, Tabs) -- Make our object inherit from Tabs. obj.title = title or mw.title.getCurrentTitle() -- Set object structure obj.categories = {} -- Set display title parameters obj.noDisplayTitle = args.notitle obj.displayTitleBase = args.title obj.displayTitleParen = args.title2 -- Set hidden status obj.isHidden = args.hide -- Set the continuity override (the "type" parameter) if args.type then local override = args.type:lower() if override ~= 'Comics' and override ~= 'TV' then obj:raiseError("if the 'type' parameter is specified, it must " .. "have a value of 'Comics' or 'TV'") end obj.continuityOverride = override end -- Set Comics and TV article names for the subject obj.TVArticle = args.TV obj.ComicsArticle = args.Comics -- Get the icon data. do local icons = {} for _, v in ipairs(args) do local t = iconData[string.lower(v)] if t then icons[string.lower(v)] = t else -- The specified icon wasn't found in the icon data, so set a -- tracking category flag. obj.hasBadParameter = true end end obj.icons = icons end return obj end -- Raise an error. If DEBUG_MODE is set to false, then errors raised here -- are caught by the export function p._main. function Tabs:raiseError(msg) local level if DEBUG_MODE then level = nil else level = 0 -- Suppress module name and line number in the error message. end error(msg, level) end -- Add a category, to be rendered at the very end of the template output. function Tabs:addCategory(cat, sort) table.insert(self.categories, {category = cat, sortKey = sort}) end -- Shortcut method for getting an icon data subtable. function Tabs:getIconData(code) return self.icons[code] end -- Whether the current title ends with /Comics. function Tabs:hasComicsTitle() return self.title.text:find('/Comics$') end -- Whether the current title ends with /TV. function Tabs:hasTVTitle() return self.title.text:find('/TV$') end -- Returns a boolean showing whether any of the icons were specified by the -- user. function Tabs:hasAnyOfIcons(...) for i = 1, select('#', ...) do if self:getIconData(select(i, ...)) then return true end end return false end -- Analyses the page name and sets {{DISPLAYTITLE}}. function Tabs:renderDisplayTitle() local pagename = self.title.text -- Exit if we have been told not to set a title or if the title begins with -- an opening parenthesis. if self.noDisplayTitle or pagename:find('^%(') then return nil end -- Find the display base and the display parentheses. local dBase = self.displayTitleBase local dParen = self.displayTitleParen if not dBase or not dParen then -- Analyse the pagename to find base part and any ending parentheses. -- /Comics is removed, and parentheses are only recognised if they are -- at the end of the pagename. local trimmedPagename = pagename:gsub('/Comics$', '') trimmedPagename = trimmedPagename:gsub('/TV$', '') local base, paren = trimmedPagename:match('^(.*)%s*%((.-)%)$') if not base then base = trimmedPagename end -- Use the values we found, but only if a value has not already been -- specified. dBase = dBase or base dParen = dParen or paren end -- Build the display string local display if dParen then display = string.format('%s <small>(%s)</small>', dBase, dParen) else display = dBase end if self.title.namespace ~= 0 then display = mw.site.namespaces[self.title.namespace].name .. ':' .. display end -- Return the expanded DISPLAYTITLE parser function. return mw.getCurrentFrame():preprocess(string.format( '{{DISPLAYTITLE:%s}}', display )) end -- Renders an tabs icon from the given icon data. It deals with the image, -- tooltip, link, and the category, but not the protection fields. function Tabs:renderIcon(data) -- Render the category at the end if it exists. if data.category then self:addCategory(data.category) end -- Render the icon and return it. local ret = {} ret[#ret + 1] = '[[File:' ret[#ret + 1] = data.image if data.tooltip then ret[#ret + 1] = '|' ret[#ret + 1] = data.tooltip end if data.link then ret[#ret + 1] = '|link=' ret[#ret + 1] = data.link end ret[#ret + 1] = ']]' return table.concat(ret) end -- Renders a protection tabs icon from the given data. If the page doesn't have -- the specified protection level, returns nil and adds a flag to add a -- tracking category later on in processing. function Tabs:renderProtectionIcon(data) if not data.protectionAction then return self:renderIcon(data) end local protectionLevel = self.title.protectionLevels[data.protectionAction] protectionLevel = protectionLevel and protectionLevel[1] if protectionLevel and protectionLevel == data.protectionLevel then return self:renderIcon(data) else self.hasIncorrectProtectionIcon = true end end -- Renders the first icon, either Comics or TV, or nil if the continuity -- couldn't be determined. This is equivalent to the previous {{Eraicon/canon}} -- template. function Tabs:renderContinuityIcon() -- First, find what continuity to use, if any. local continuity, isUsingCategory if self.continuityOverride == 'TV' then continuity = 'TV' if not self:hasAnyOfIcons('real') then isUsingCategory = true end elseif self.title.namespace == 0 then if self:hasTVTitle() then continuity = 'TV' isUsingCategory = true elseif self:hasComicsTitle() then continuity = 'Comics' isUsingCategory = true elseif self.TVArticle then continuity = 'Comics' isUsingCategory = true elseif self.ComicsArticle then continuity = 'TV' isUsingCategory = true elseif exists(self.title.text .. '/TV') then continuity = 'Comics' isUsingCategory = true elseif exists(self.title.text .. '/Comics') then continuity = 'TV' isUsingCategory = true elseif self:hasAnyOfIcons('pre', 'btr', 'old', 'imp', 'reb', 'new', 'njo', 'leg') then continuity = 'TV' if self:hasAnyOfIcons('real') then isUsingCategory = false else isUsingCategory = true end elseif self:hasAnyOfIcons('inf', 'noncanon') then continuity = 'TV' isUsingCategory = false elseif self:hasAnyOfIcons('real') then if self.continuityOverride == 'Comics' then continuity = 'Comics' end isUsingCategory = false else continuity = 'Comics' isUsingCategory = true end end -- Generate the icon data and make the icon. if continuity == 'Comics' then local data = { image = 'Eras-canon.png', tooltip = 'This article details a subject that is from the comics.', link = 'Comics' } if isUsingCategory then data.category = 'Comics articles' end return self:renderIcon(data) elseif continuity == 'TV' then local data = { image = 'Eras-legends.png', tooltip = 'This article details a subject that falls under the TV brand.', link = 'Powers (TV series)' } if isUsingCategory then data.category = 'TV articles' end return self:renderIcon(data) end end -- Renders the icons that respond to a publishing era. function Tabs:renderPublishingIcons() if self.continuityOverride ~= 'Comics' and not self.TVArticle and not self:hasComicsTitle() then local ret = {} local codes = {'pre', 'btr', 'old', 'imp', 'reb', 'new', 'njo', 'leg', 'inf'} for _, code in ipairs(codes) do local data = self:getIconData(code) if data then ret[#ret + 1] = self:renderIcon(data) end end return table.concat(ret) end end -- Renders other icons, e.g. featured article status and protection status. function Tabs:renderNonPublishingIcons() local ret = {} local codes = {'real', 'featured', 'former', 'good', 'fga', 'comp', 'fca'} for _, code in ipairs(codes) do local data = self:getIconData(code) if data then ret[#ret + 1] = self:renderIcon(data) end end local protectionCodes = {'fprot', 'sprot', 'ssprot', 'mprot', 'uprot'} for _, code in ipairs(protectionCodes) do local data = self:getIconData(code) if data then ret[#ret + 1] = self:renderProtectionIcon(data) end end return table.concat(ret) end -- Render all the icons and eclose them in a surrounding div tag. function Tabs:renderIcons() local icons = {} icons[#icons + 1] = self:renderContinuityIcon() icons[#icons + 1] = self:renderPublishingIcons() icons[#icons + 1] = self:renderNonPublishingIcons() icons = table.concat(icons) local root = mw.html.create('div') root :attr('id', 'title-eraicons') :css('float', 'right') :css('position', 'static') :css('display', 'none') :wikitext(icons) return tostring(root) end -- Renders the Comics and TV tabs for articles that are in both -- continuities. function Tabs:renderComicsTab() if self.isHidden or self.title.namespace ~= 0 then -- Exit if we have been explicitly hidden or if we are not in the main -- namespace. return nil end -- Find the page type, comics title, and TV title. local pageType, ComicsTitle, TVTitle if self.TVArticle then pageType = 'Comics' ComicsTitle = self.title.text TVTitle = self.TVArticle elseif self.ComicsArticle then pageType = 'TV' ComicsTitle = self.ComicsArticle TVTitle = self.title.text elseif self:hasComicsTitle() then pageType = 'Comics' ComicsTitle = self.title.text TVTitle = ComicsTitle:match('^(.*)/Comics$') or ComicsTitle elseif self:hasTVTitle() then pageType = 'TV' TVTitle = self.title.text ComicsTitle = TVTitle:match('^(.*)/TV$') or TVTitle elseif exists(self.title.text .. '/TV') then pageType = 'Comics' TVTitle = self.title.text .. '/TV' ComicsTitle = self.title.text elseif exists(self.title.text .. '/Comics') then pageType = 'TV' ComicsTitle = self.title.text .. '/Comics' TVTitle = self.title.text else -- Could not determine that the article has both a Comics and a TV -- version, so exit. return nil end if self:hasComicsTitle() then self:addCategory('Articles with /Comics') end -- Add categories. if pageType == 'Comics' then self:addCategory('Comics articles with TV counterparts') elseif pageType == 'TV' then self:addCategory('TV articles with Comics counterparts') else self:addCategory('Outliers') end -- Make the table root. local root = mw.html.create('table') root :attr('id', 'comicstab') :css('text-align', 'center') :css('padding', '0') :css('margin', '0 0 5px 0') :css('border-left', '0') :css('border-right', '0') :css('border-top', '0') :css('border-bottom', '7px solid #002e54') :css('border-spacing', '0') :css('border-collapse', 'collapse') :css('width', '100%') :css('vertical-align', 'top') local row = root:tag('tr') -- This makes one Comics/TV cell. Having this as a function rather than -- doing it with chaining allows us to avoid putting the same code in twice. local function makeCell(id, color, image, link, tooltip) local cell = mw.html.create('td') cell :attr('id', id) :css('padding', '0 0 5px 0') :css('background-color', color) :css('line-height', '0.95em') :css('font-size', '150%') :css('font-weight', 'bold') :css('width', '20px') :css('vertical-align', 'top') :tag('span') :addClass('content-bg rtop') :css('background', '#ffffff') :tag('span') :addClass('r1') :css('background', color) :done() :tag('span') :addClass('r2') :css('background', color) :done() :tag('span') :addClass('r3') :css('background', color) :done() :tag('span') :addClass('r4') :css('background', color) :done() :done() :wikitext(string.format( ' [[File:%s|link=%s|%s]]', image, link, tooltip )) return cell end local foregroundColor = '#002e54' local backgroundColor = '#d8e9fc' -- Make the comics cell. do local id = 'comicstab-comics' local link = ComicsTitle local color, image, tooltip if pageType == 'comics' then color = foregroundColor image = 'Tab-canon-white.png' tooltip = 'This article covers the Comics version of this subject.' else color = backgroundColor image = 'Tab-canon-black.png' tooltip = "Click here for Powers Wiki's article on the Comics " .. "version of this subject." end row:node(makeCell(id, color, image, link, tooltip)) end -- First separator cell row:tag('td') :attr('id', 'comicstab-separator1') :css('width', '3px') :wikitext(' ') -- Make the TV cell do local id = 'comicstab-TV' local link = TVTitle local color, image, tooltip if pageType ~= 'comics' then -- is a TV page color = foregroundColor image = 'Tab-legends-white.png' tooltip = 'This article covers the TV version of this subject.' else -- is a Comics page color = backgroundColor image = 'Tab-legends-black.png' tooltip = "Click here for Powers Wiki's article on the TV " .. "version of this subject." end row:node(makeCell(id, color, image, link, tooltip)) end -- Second separator cell row:tag('td') :attr('id', 'comicstab-separator2') :css('width', '3000px') :wikitext(' ') return tostring(root) end -- Render all the categories that were specified using Tabs:addCategory or with -- category flags. function Tabs:renderCategories() local fullPagename = self.title.prefixedText if fullPagename == 'Template:Tabs' or fullPagename == 'Template:Eraicon' then -- Exit if we are on a blacklisted page. return nil end local pagename = self.title.text -- Renders one category. local function renderCategory(cat, sort) return string.format( '[[%s:%s|%s]]', 'Category', cat, sort or pagename ) end local ret = {} -- Render categories from Tabs:addCategory for i, t in ipairs(self.categories) do ret[i] = renderCategory(t.category, t.sortKey) end -- Render categories from category flags. if self.hasBadParameter then ret[#ret + 1] = renderCategory( 'Pages with bad parameters in Template:Tabs' ) end if self.hasIncorrectProtectionIcon then ret[#ret + 1] = renderCategory( 'Pages with incorrect protection icons' ) end return table.concat(ret) end -- This method is called when the tostring function is used on the Tabs object. -- (This works in a similar fashion to Tabs.__index above.) It calls all the -- top-level render methods and returns the final output. function Tabs:__tostring() local ret = {} ret[#ret + 1] = self:renderDisplayTitle() ret[#ret + 1] = self:renderIcons() ret[#ret + 1] = self:renderComicsTab() ret[#ret + 1] = self:renderCategories() return table.concat(ret) end ------------------------------------------------------------------------------- -- Exports ------------------------------------------------------------------------------- local p = {} -- This function is the entry point from other Lua modules. function p._main(args) -- Define a function to call from pcall so that we can catch any errors -- and display them to the user rather than the cryptic "Script error". -- (It's not so cryptic if you click on it to see the error message, but -- not so many users know to do that.) local function getTabsResult () local tabsObj = Tabs.new(args) return tostring(tabsObj) end -- Get the result. We only catch errors if debug mode is set to false. local success, result if DEBUG_MODE then success = true result = getTabsResult() else success, result = pcall(getTabsResult) end -- Return the result if there were no errors, and a formatted error message -- if there were. if success then return result else return string.format( '<strong class="error">[[Template:Tabs]] error: %s.</strong>' .. '[[' .. 'Category:Pages with bad parameters in Template:Tabs]]', result -- this is the error message ) end end -- This is the function accessed from wikitext. It must be accessed through -- a template. The template should transclude only the text -- "{{#invoke:Tabs|main}}", and then when that template is used, any arguments -- passed to it are magically sent through to the module. function p.main(frame) local args = {} for k, v in pairs(frame:getParent().args) do v = v:match('^%s*(.-)%s*$') -- trim whitespace if v ~= '' then args[k] = v end end return p._main(args) end return p -- </nowiki> -- [[Category:Templates|{{PAGENAME}}]]
Summary:
Please note that all contributions to the Powers Wiki are considered to be released under the CC-BY-SA
Cancel
Editing help
(opens in new window)
Follow on IG
TikTok
Join Fan Lab