Dokumentaci tohoto modulu lze vytvořit na stránce Modul:Erasportable/Dokumentace
-- <nowiki>
--Zdroj - starwars.wikia.com
-------------------------------------------------------------------------------
-- Module:Eras
--
-- This module renders the icons in the top-right corner of articles, as well
-- as the Canon and Legends tabs for pages with a Canon/Legends counterpart.
-- It also formats the page title with {{DISPLAYTITLE}}. It is a rewrite of
-- [[Template:Eras]].
-------------------------------------------------------------------------------
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 = "Era-pre-portable.png",
tooltip = "Obsah tohoto článku spadá před období před Starou republikou",
link = "Předrepublikové období"
},
btr = {
image = "Era-pre-portable.png",
tooltip = "Obsah tohoto článku spadá před období Staré republiky.",
link = "Před Republikou"
},
old = {
image = "Era-old-portable.png",
tooltip = "Obsah tohoto článku spadá do období Staré republiky.",
link = "Období Staré republiky"
},
imp = {
image = "Era-imp-portable.png",
tooltip = "Obsah tohoto článku spadá do období vzestupu Impéria.",
link = "Období vzestupu Impéria"
},
reb = {
image = "Era-reb-portable.png",
tooltip = "Obsah tohoto článku spadá do období Povstání.",
link = "Období Povstání"
},
new = {
image = "Era-new-portable.png",
tooltip = "Obsah tohoto článku spadá do období Nové republiky.",
link = "Období Nové republiky"
},
njo = {
image = "Era-njo-portable.png",
tooltip = "Obsah tohoto článku spadá do období Nového řádu Jedi.",
link = "Období Nového řádu Jedi"
},
leg = {
image = "Era-leg-portable.png",
tooltip = "Obsah tohoto článku spadá do období Dědictví.",
link = "Období Dědictví"
},
inf = {
image = "Era-inf-portable.png",
tooltip = "Obsah tohoto článku je součástí Star Wars Infinities.",
link = "Infinities"
},
real = {
image = "Era-real-portable.png",
tooltip = "Obsah tohoto článku je ze skutečného světa.",
link = "Category:Star Wars Entertainment"
},
featured = {
image = "Era-featured-portable.png",
tooltip = "Toto je doporučený článek.",
link = "Czech Star Wars Wiki:Doporučené články",
category = "Doporučené články"
},
former = {
image = "Era-defeatured-portable.png",
tooltip = "Toto je bývalý doporučený článek.",
link = "Czech Star Wars Wiki:Doporučené články",
category = "Bývalé doporučené články"
},
good = {
image = "Era-good-portable.png",
tooltip = "Toto je dobrý článek.",
link = "Czech Star Wars Wiki:Dobré články",
category = "Dobré články"
},
fga = {
image = "Era-formergood-portable.png",
tooltip = "Toto je bývalý dobrý článek.",
link = "Czech Star Wars Wiki:Dobré články",
category = "Bývalé dobré články"
},
comp = {
image = "Era-comp-portable.png",
tooltip = "Toto je ucelený článek.",
link = "Czech Star Wars Wiki:Ucelené články",
category = "Ucelené články"
},
fca = {
image = "Era-compformer-portable.png",
tooltip = "Toto je bývalý ucelený článek.",
link = "Czech Star Wars Wiki:Ucelené články",
category = "Bývalé ucelené články"
},
fprot = {
protectionAction = "edit",
protectionLevel = "sysop",
image = "Era-Fprotect-portable.png",
tooltip = "Tento článek je chráněn.",
link = "Czech Star Wars Wiki:Ochrana článků",
category = "Chráněné články"
},
sprot = {
protectionAction = "edit",
protectionLevel = "autoconfirmed",
image = "Era-Sprotect-portable.png",
tooltip = "Tento článek je polochráněn.",
link = "Czech Star Wars Wiki:Ochrana článků",
category = "Polochráněné články"
},
ssprot = {
image = "Era-Ssprotect-portable.png",
tooltip = "Tento článek je super-polochráněn.",
link = "Czech Star Wars Wiki:Ochrana článků",
category = "Super-polochráněné články"
},
mprot = {
protectionAction = "move",
protectionLevel = "sysop",
image = "Era-Mprotect-portable.png",
tooltip = "Tento článek je chráněn proti přesunu.",
link = "Czech Star Wars Wiki:Ochrana článků",
category = "Články chráněné proti přesunu"
},
uprot = {
protectionAction = "upload",
protectionLevel = "sysop",
image = "Era-Uprotect-portable.png",
tooltip = "Tento soubor je chráněn proti přepsání.",
link = "Czech Star Wars Wiki:Ochrana článků",
category = "Soubory chráněné proti přepsání"
},
noncanon = {
image = "Era-inf-portable.png",
tooltip = "Obsah tohoto článku je považován za nekanonický."
}
}
-------------------------------------------------------------------------------
-- 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
-------------------------------------------------------------------------------
-- Eras class
-------------------------------------------------------------------------------
-- The eras 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 Eras = {}
Eras.__index = Eras -- Set up inheritance for tables that use Eras as a metatable.
-- This function makes a new eras object. Here we set all the values from the
-- arguments and do any preprocessing that we need.
function Eras.new(args, title)
local obj = setmetatable({}, Eras) -- Make our object inherit from Eras.
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 "typ" parameter)
if args.typ then
local override = args.typ:lower()
if override ~= 'kanon' and override ~= 'legendy' and override ~= 'kánon' then
obj:raiseError("pokud je použit parametr 'typ', musí " ..
"mít hodnotu 'kanon' nebo 'legendy'")
end
if override == 'kánon' then
obj.continuityOverride='kanon'
else
obj.continuityOverride = override
end
end
-- Set canon and legends article names for the subject
obj.legendsArticle = args.legendy
obj.canonArticle = args.kanon
-- 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 Eras: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 Eras:addCategory(cat, sort)
table.insert(self.categories, {category = cat, sortKey = sort})
end
-- Shortcut method for getting an icon data subtable.
function Eras:getIconData(code)
return self.icons[code]
end
-- Whether the current title ends with /Canon.
function Eras:hasCanonTitle()
return self.title.text:find('/Kánon$')
end
-- Whether the current title ends with /Legends.
function Eras:hasLegendsTitle()
return self.title.text:find('/Legendy$')
end
-- Returns a boolean showing whether any of the icons were specified by the
-- user.
function Eras: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 Eras: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.
-- /Canon is removed, and parentheses are only recognised if they are
-- at the end of the pagename.
local trimmedPagename = pagename:gsub('/Kánon$', '')
trimmedPagename = pagename:gsub('/Legendy$', '')
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 eras icon from the given icon data. It deals with the image,
-- tooltip, link, and the category, but not the protection fields.
function Eras: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] = '[[Soubor:'
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 eras 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 Eras: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 Canon or Legends, or nil if the continuity
-- couldn't be determined. This is equivalent to the previous {{Eraicon/canon}}
-- template.
function Eras:renderContinuityIcon()
-- First, find what continuity to use, if any.
local continuity, isUsingCategory
if self.continuityOverride == 'legendy' then
continuity = 'legendy'
if not self:hasAnyOfIcons('real') then
isUsingCategory = true
end
elseif self.title.namespace == 0 then
if self:hasLegendsTitle() then
continuity = 'legendy'
isUsingCategory = true
elseif self:hasCanonTitle() then
continuity = 'kánon'
isUsingCategory = true
elseif self.legendsArticle then
continuity = 'kánon'
isUsingCategory = true
elseif self.canonArticle then
continuity = 'legendy'
isUsingCategory = true
elseif exists(self.title.text .. '/Legendy') then
continuity = 'kánon'
isUsingCategory = true
elseif exists(self.title.text .. '/Kánon') then
continuity = 'legendy'
isUsingCategory = true
elseif self:hasAnyOfIcons('pre', 'btr', 'old', 'imp', 'reb', 'new',
'njo', 'leg')
then
continuity = 'legendy'
if self:hasAnyOfIcons('real') then
isUsingCategory = false
else
isUsingCategory = true
end
elseif self:hasAnyOfIcons('inf', 'noncanon') then
continuity = 'legendy'
isUsingCategory = false
elseif self:hasAnyOfIcons('real') then
if self.continuityOverride == 'kanon' then
continuity = 'kánon'
end
isUsingCategory = false
else
continuity = 'kánon'
isUsingCategory = true
end
end
-- Generate the icon data and make the icon.
if continuity == 'kánon' then
local data = {
image = 'Infobox-canon.png',
--image = 'Eras-legends.png',
tooltip = 'Obsah tohoto článku je považován za kanonický',
link = 'Kánon'
}
if isUsingCategory then
data.category = 'Kanonické články'
end
return self:renderIcon(data)
elseif continuity == 'legendy' then
local data = {
image = 'Infobox-legends.png',
--image = 'Eras-legends.png',
tooltip = 'Obsah tohoto článku spadá mezi Legendy.',
link = 'Star Wars Legendy'
}
if isUsingCategory then
data.category = 'Články z Legend'
end
return self:renderIcon(data)
end
end
-- Renders the icons that respond to a publishing era.
function Eras:renderPublishingIcons()
if self.continuityOverride ~= 'kanon'
and not self.legendsArticle
and not self:hasCanonTitle()
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 Eras: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
function Eras:renderCanonTab()
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, canon title, and legends title.
local pageType, canonTitle, legendsTitle
if self.legendsArticle then
pageType = 'kánon'
canonTitle = self.title.text
legendsTitle = self.legendsArticle
elseif self.canonArticle then
pageType = 'legendy'
canonTitle = self.canonArticle
legendsTitle = self.title.text
elseif self:hasCanonTitle() then
pageType = 'kánon'
canonTitle = self.title.text
legendsTitle = canonTitle:match('^(.*)/Kánon$') or canonTitle
elseif self:hasLegendsTitle() then
pageType = 'legendy'
legendsTitle = self.title.text
canonTitle = legendsTitle:match('^(.*)/Legendy$') or legendsTitle
elseif exists(self.title.text .. '/Legendy') then
pageType = 'kánon'
legendsTitle = self.title.text .. '/Legendy'
canonTitle = self.title.text
elseif exists(self.title.text .. '/Kánon') then
pageType = 'legendy'
canonTitle = self.title.text .. '/Kánon'
legendsTitle = self.title.text
else
-- Could not determine that the article has both a Canon and a Legends
-- version, so exit.
return nil
end
-- Add categories.
if pageType == 'kánon' then
self:addCategory('Kanonické články s protějšky z Legend')
elseif pageType == 'legendy' then
self:addCategory('Články z Legend s kanonickými protějšky')
else
self:addCategory('Nezařazené') --Outliers
end
local root = mw.html.create('div')
root:attr('id', 'canon-legends-switch')
--local row = root:tag('span')
local function makeCell(image, link)
local cell = mw.html.create('span')
cell
--:attr('id', id)
--:css('padding', '4px 0 4px 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')
-- :done()
:wikitext(string.format(
' [[Soubor:%s|170px|link=%s]]',
--image, link, tooltip
image, link
))
return cell
end
-- local foregroundColor = '#006cb0'
--local backgroundColor = '#99CCFF'
if pageType == 'kánon' then
--color = foregroundColor
--image = 'Tab-canon-white.png'
--to
--local id = 'canontab-canon'
local link = legendsTitle
-- color = backgroundColor
--image = 'Eras-legends.png'
image = 'Infobox-legends.png'
tooltip = "Klikni zde pro legendární " ..
"verzi článku."
--root:node(makeCell(image, link))
root
:wikitext(string.format(
' [[%s|Přejít na legendární verzi článku]]',
--image, link, tooltip
link
))
else
--local id = 'canontab-legends'
local link = canonTitle
-- color = backgroundColor
--image = 'Eras-legends.png'
image = 'Tab-canon-black.png'
tooltip = "Klikni zde pro kanonickou " ..
"verzi článku."
--root:node(makeCell( image, link))
root
:wikitext(string.format(
' [[%s|Přejít na kanonickou verzi článku]]',
--image, link, tooltip
link
))
end
return tostring(root)
end
-- Render all the icons and eclose them in a surrounding div tag.
function Eras:renderContIcons()
local icons = {}
icons[#icons + 1] = self:renderContinuityIcon()
icons = table.concat(icons)
--local root = mw.html.create('header')
local root = mw.html.create('span')
root
--:attr('id', 'title-eraicons')
--:css('text-align', 'right')
--:css('display', 'block')
--:css('border-top', '4px solid #006CB0')
:wikitext(icons)
return tostring(root)
end
-- Render all the icons and eclose them in a surrounding div tag.
function Eras:renderIcons()
local icons = {}
icons[#icons + 1] = self:renderPublishingIcons()
icons[#icons + 1] = self:renderNonPublishingIcons()
icons = table.concat(icons)
--local root = mw.html.create('header')
local root = mw.html.create('div')
root
--:attr('id', 'title-eraicons')
--:css('text-align', 'right')
--:css('display', 'block')
--:css('border-top', '4px solid #006CB0')
:wikitext(icons)
return tostring(root)
end
-- Render all the categories that were specified using Eras:addCategory or with
-- category flags.
function Eras:renderCategories()
local fullPagename = self.title.prefixedText
if fullPagename == 'Template:Eras' 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 Eras: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(
'Stránky se špatnými parametry v šabloně Období'
)
end
if self.hasIncorrectProtectionIcon then
ret[#ret + 1] = renderCategory(
'Stránky s nesprávnou ikonou ochrany'
)
end
return table.concat(ret)
end
-- This method is called when the tostring function is used on the Eras object.
-- (This works in a similar fashion to Eras.__index above.) It calls all the
-- top-level render methods and returns the final output.
function Eras:__tostring()
local ret = {}
ret[#ret + 1] = self:renderDisplayTitle()
ret[#ret + 1] = self:renderIcons()
ret[#ret + 1] = self:renderContIcons()
ret[#ret + 1] = self:renderCanonTab()
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 getErasResult ()
local erasObj = Eras.new(args)
return tostring(erasObj)
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 = getErasResult()
else
success, result = pcall(getErasResult)
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:Eras]] chyba: %s.</strong>' ..
'[[' .. 'Category:Stránky s nesprávnou ikonou ochrany]]',
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:Eras|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:Eras utility templates|{{PAGENAME}}]]