Moduuli:Eras
Jedipediasta, vapaasta Tähtien sota-tietosanakirjasta tänään, 30. heinäkuuta 2025
Siirry navigaatioonSiirry hakuun
Tämän moduulin ohjeistuksen voi tehdä sivulle Moduuli:Eras/ohje
1 -- <nowiki>
2
3 -------------------------------------------------------------------------------
4 -- Module:Eras
5 --
6 -- This module renders the icons in the top-right corner of articles, as well
7 -- as the Canon and Legends tabs for pages with a Canon/Legends counterpart.
8 -- It also formats the page title with {{DISPLAYTITLE}}. It is a rewrite of
9 -- [[Template:Eras]].
10 -------------------------------------------------------------------------------
11
12 local DEBUG_MODE = false -- if true, errors are not caught
13
14 -------------------------------------------------------------------------------
15 -- Icon data
16 -------------------------------------------------------------------------------
17
18 --[[
19 -- This table stores data for all the icons displayed in the top-right. It can
20 -- have the following fields:
21 -- * image - the icon image name, minus any "File:" prefix (required).
22 -- * tooltip - the icon tooltip (optional).
23 -- * link - the page to link from the icon (optional).
24 -- * category - a category to go with the icon, minus any "Category:" prefix
25 -- (optional).
26 -- * protectionAction - for protection icons, an action such as "edit" or "move"
27 -- to check (optional).
28 -- * protectionLevel - for protection icons, the protection level to check,
29 -- such as "sysop". If the page doesn't have the right protection level
30 -- it is put in a tracking category and the icon is not displayed
31 -- (optional).
32 -- Note: this is just a convenient place to store the data. The subtables are
33 -- accessed from the code manually, so adding new subtables won't automatically
34 -- add new icons, and removing subtables may break things.
35 --]]
36
37 local iconData = {
38 can = {
39 image = 'Eras-canon-edit.png',
40 tooltip = 'Tämän artikkelin aihe kuuluu kaanoniin.',
41 link = 'Kaanon'
42 },
43 leg = {
44 image = 'LegendsBanner.png',
45 tooltip = 'Tämän artikkelin aihe kuuluu Legendsiin.',
46 link = 'Star Wars Legends'
47 },
48 dotj = {
49 image = "Era-dotj.png",
50 tooltip = "Tämän artikkelin aihe esiintyi jedien nousun aikakaudella."
51 },
52 tor = {
53 image = "Era-tor.png",
54 tooltip = "Tämän artikkelin aihe esiintyi Vanhan tasavallan aikakaudella."
55 },
56 thr = {
57 image = "Era-thr.png",
58 tooltip = "Tämän artikkelin aihe esiintyi Uljaan tasavallan aikakaudella."
59 },
60 fotj = {
61 image = "Era-fotj.png",
62 tooltip = "Tämän artikkelin aihe esiintyi jedien tuhon aikakaudella."
63 },
64 rote = {
65 image = "Era-reb.png",
66 tooltip = "Tämän artikkelin aihe esiintyi Imperiumin aikakaudella."
67 },
68 aor = {
69 image = "Era-aor.png",
70 tooltip = "Tämän artikkelin aihe esiintyi kapinan aikakaudella."
71 },
72 tnr = {
73 image = "Era-tnr.png",
74 tooltip = "Tämän artikkelin aihe esiintyi Uuden tasavallan aikakaudella."
75 },
76 rofo = {
77 image = "Era-dotj.png",
78 tooltip = "Tämän artikkelin aihe esiintyi Ensimmäisen ritarikunnan aikakaudella."
79 },
80 cnjo = {
81 image = "Era-cnjo.png",
82 tooltip = "Tämän artikkelin aihe esiintyi uuden jediritarikunnan aikakaudella."
83 },
84 pre = {
85 image = "Era-btr.png",
86 tooltip = "Tämän artikkelin aihe esiintyi Tasavaltaa edeltävällä aikakaudella.",
87 link = "Tasavaltaa edeltävä aikakausi"
88 },
89 btr = {
90 image = "Era-btr.png",
91 tooltip = "Tämän artikkelin aihe esiintyi Tasavaltaa edeltävällä aikakaudella.",
92 link = "Tasavaltaa edeltävä aikakausi"
93 },
94 old = {
95 image = "Era-old.png",
96 tooltip = "Tämän artikkelin aihe esiintyi Vanhan Tasavallan aikakaudella.",
97 link = "Vanhan Tasavallan aikakausi"
98 },
99 imp = {
100 image = "Era-imp.png",
101 tooltip = "Tämän artikkelin aihe esiintyi Imperiumin nousun aikakaudella.",
102 link = "Imperiumin nousun aikakausi"
103 },
104 reb = {
105 image = "Era-reb.png",
106 tooltip = "Tämän artikkelin aihe esiintyi kapinallisten aikakaudella.",
107 link = "Kapinallisten aikakausi"
108 },
109 new = {
110 image = "Era-new.png",
111 tooltip = "Tämän artikkelin aihe esiintyi Uuden tasavallan aikakaudella.",
112 link = "Uuden tasavallan aikakausi (tosimaailma)"
113 },
114 njo = {
115 image = "Era-njo.png",
116 tooltip = "Tämän artikkelin aihe esiintyi uuden jediritarikunnan aikakaudella.",
117 link = "Uuden jediritarikunnan aikakausi"
118 },
119 lgc = {
120 image = "Era-leg.png",
121 tooltip = "Tämän artikkelin aihe esiintyi perinnön aikakaudella.",
122 link = "Perinnön aikakausi"
123 },
124 inf = {
125 image = "30px-Era-inf.png",
126 tooltip = "Tämän artikkelin aihe on osa Star Wars Infinitiesiä.",
127 link = "Infinities"
128 },
129 real = {
130 image = "Era-real.png",
131 tooltip = "Tämä artikkeli kertoo todellisesta asiasta tai henkilöstä.",
132 link = "Luokka:Tosimaailma"
133 },
134 ss = {
135 image = "FeaturedIcon.png",
136 tooltip = "Tämä on suositeltu sivu.",
137 link = "Jedipedia:Suositeltu sivu",
138 category = "Suositellut sivut"
139 },
140 ess = {
141 image = "EntinenSuositeltu.png",
142 tooltip = "Tämä on entinen suositeltu sivu.",
143 link = "Jedipedia:Suositeltu sivu"
144 },
145 ha = {
146 image = "GoodIcon.png",
147 tooltip = "Tämä on hyvä artikkeli.",
148 link = "Jedipedia:Hyvä artikkeli",
149 category = "Hyvät artikkelit"
150 },
151 eha = {
152 image = "30px-FormerGAicon.png",
153 tooltip = "Tämä on entinen hyvä artikkeli.",
154 link = "Jedipedia:Hyvä artikkeli"
155 },
156 vkp = {
157 image = "Queicon.png",
158 tooltip = "Tällä artikkelin nimellä ei ole virallista käännöstä.",
159 link = "Jedipedia:Virallisen käännöksen puuttuminen",
160 category = "Virallisten käännösten puutteessa olevat artikkelit"
161 },
162 fprot = {
163 protectionAction = "edit",
164 protectionLevel = "sysop",
165 image = "Padlockicon3.png",
166 tooltip = "Tämä sivu on suojattu muokkauksilta.",
167 link = "Jedipedia:Suojauskäytäntö"
168 },
169 sprot = {
170 protectionAction = "edit",
171 protectionLevel = "autoconfirmed",
172 image = "Padlockicon2.png",
173 tooltip = "Tämä sivu on osittain suojattu muokkauksilta.",
174 link = "Jedipedia:Suojauskäytäntö"
175 },
176 mprot = {
177 protectionAction = "move",
178 protectionLevel = "sysop",
179 image = "Padlockicon4.png",
180 tooltip = "Tämä sivu on suojattu siirroilta.",
181 link = "Jedipedia:Suojauskäytäntö"
182 },
183 uprot = {
184 protectionAction = "upload",
185 protectionLevel = "sysop",
186 image = "Padlockicon6.png",
187 tooltip = "Tämä tiedosto on suojattu tallennuksilta.",
188 link = "Jedipedia:Suojauskäytäntö"
189 }
190 }
191
192 -------------------------------------------------------------------------------
193 -- Helper functions
194 -------------------------------------------------------------------------------
195
196 -- Find whether the specified page exists. We use pcall to catch errors if we
197 -- are over the expensive parser function count limit, or a number of other
198 -- juicy errors. This function increases the expensive parser function count
199 -- for every new page called.
200 local function exists(page)
201 local success, title = pcall(mw.title.new, page)
202 return success and title and title.exists or false
203 end
204
205 local function isRedirect(page)
206 local success, title = pcall(mw.title.new, page)
207 return success and title and title.isRedirect or false
208 end
209
210 -------------------------------------------------------------------------------
211 -- Eras class
212 -------------------------------------------------------------------------------
213
214 -- The eras class does all of the heavy lifting in the module. We use a class
215 -- rather than normal functions so that we can avoid passing lots of different
216 -- values around for each different function.
217
218 local Eras = {}
219 Eras.__index = Eras -- Set up inheritance for tables that use Eras as a metatable.
220
221 -- This function makes a new eras object. Here we set all the values from the
222 -- arguments and do any preprocessing that we need.
223 function Eras.new(args, title)
224 local obj = setmetatable({}, Eras) -- Make our object inherit from Eras.
225 obj.title = title or mw.title.getCurrentTitle()
226
227 -- Set object structure
228 obj.categories = {}
229
230 -- Näytettävän otsikon parametrit
231 obj.noDisplayTitle = args.notitle
232 if args.title or args.title2 then
233 obj.displayTitleBase = args.title
234 obj.displayTitleParen = args.title2
235 else
236 obj.displayTitleBase = args.otsikko
237 obj.displayTitleParen = args.otsikko2
238 end
239
240 -- Set hidden status
241 obj.isHidden = args.hide
242
243 -- Set notoc value
244 obj.hideToc = args.notoc
245
246 -- Jatkumon määrittäminen (parametri "tyyppi")
247 if args.tyyppi then
248 local override = args.tyyppi:lower()
249 if override ~= 'kaanon' and override ~= 'legends' then
250 obj:raiseError("jos parametri 'tyyppi' on määritetty, " ..
251 "sen on oltava 'kaanon' tai 'legends'")
252 end
253 obj.continuityOverride = override
254 end
255
256 -- Kaanon- ja Legends-nimet artikkelille
257 obj.legendsArticle = args.legends
258 obj.canonArticle = args.kaanon
259
260 -- Kuvakkeiden tiedot.
261 do
262 local icons = {}
263 for _, v in ipairs(args) do
264 local t = iconData[string.lower(v)]
265 if t then
266 icons[string.lower(v)] = t
267 else
268 -- Annettua kuvaketta ei ole tiedoissa, joten
269 -- lisätään virheluokka.
270 obj.hasBadParameter = true
271 end
272 end
273 obj.icons = icons
274 end
275
276 return obj
277 end
278
279 -- Ilmoittaa virheestä. Jos DEBUG_MODE on false, tässä olevat virheet
280 -- huomataan funktiossa p._main.
281 function Eras:raiseError(msg)
282 local level
283 if DEBUG_MODE then
284 level = nil
285 else
286 level = 0 -- Suppress module name and line number in the error message.
287 end
288 error(msg, level)
289 end
290
291 -- Add a category, to be rendered at the very end of the template output.
292 function Eras:addCategory(cat, sort)
293 table.insert(self.categories, {category = cat, sortKey = sort})
294 end
295
296 -- Shortcut method for getting an icon data subtable.
297 function Eras:getIconData(code)
298 return self.icons[code]
299 end
300
301 -- Päättyykö nykyinen otsikko /Kaanon.
302 function Eras:hasCanonTitle()
303 return self.title.text:find('/Kaanon$')
304 end
305
306 -- Päättyykö nykyinen otsikko /Legends.
307 function Eras:hasLegendsTitle()
308 return self.title.text:find('/Legends$')
309 end
310
311 -- Returns a boolean showing whether any of the icons were specified by the
312 -- user.
313 function Eras:hasAnyOfIcons(...)
314 for i = 1, select('#', ...) do
315 if self:getIconData(select(i, ...)) then
316 return true
317 end
318 end
319 return false
320 end
321
322 -- Analysoi sivun nimen ja asettaa {{DISPLAYTITLE}}:n.
323 function Eras:renderDisplayTitle()
324 local pagename = self.title.text
325
326 -- Exit if we have been told not to set a title or if the title begins with
327 -- an opening parenthesis.
328 if self.noDisplayTitle or pagename:find('^%(') then
329 return nil
330 end
331
332 -- Find the display base and the display parentheses.
333 local dBase = self.displayTitleBase
334 local dParen = self.displayTitleParen
335 if not dBase or not dParen then
336 -- Analyse the pagename to find base part and any ending parentheses.
337 -- /Canon is removed, and parentheses are only recognised if they are
338 -- at the end of the pagename.
339 local trimmedPagename = pagename:gsub('/Kaanon$', '')
340 trimmedPagename = trimmedPagename:gsub('/Legends$', '')
341 local base, paren = trimmedPagename:match('^(.*)%s*%((.-)%)$')
342 if not base then
343 base = trimmedPagename
344 end
345 -- Use the values we found, but only if a value has not already been
346 -- specified.
347 dBase = dBase or base
348 dParen = dParen or paren
349 end
350
351 -- Build the display string
352 local display
353 if dParen then
354 display = string.format('%s <small>(%s)</small>', dBase, dParen)
355 else
356 display = dBase
357 end
358 if self.title.namespace ~= 0 then
359 display = mw.site.namespaces[self.title.namespace].name .. ':' .. display
360 end
361
362 -- Return the expanded DISPLAYTITLE parser function.
363 return mw.getCurrentFrame():callParserFunction('DISPLAYTITLE', display)
364 end
365
366 -- Renders an eras icon from the given icon data. It deals with the image,
367 -- tooltip, link, and the category, but not the protection fields.
368 function Eras:renderIcon(data)
369 -- Render the category at the end if it exists.
370 if data.category then
371 self:addCategory(data.category)
372 end
373 -- Render the icon and return it.
374 local ret = {}
375 ret[#ret + 1] = '[[Tiedosto:'
376 ret[#ret + 1] = data.image
377 if data.tooltip then
378 ret[#ret + 1] = '|'
379 ret[#ret + 1] = data.tooltip
380 end
381 if data.link then
382 ret[#ret + 1] = '|link='
383 ret[#ret + 1] = data.link
384 end
385 ret[#ret + 1] = '|x30px]]'
386 return table.concat(ret)
387 end
388
389 -- Renders a protection eras icon from the given data. If the page doesn't have
390 -- the specified protection level, returns nil and adds a flag to add a
391 -- tracking category later on in processing.
392 function Eras:renderProtectionIcon(data)
393 if not data.protectionAction then
394 return self:renderIcon(data)
395 end
396 local protectionLevel = self.title.protectionLevels[data.protectionAction]
397 protectionLevel = protectionLevel and protectionLevel[1]
398 if protectionLevel and protectionLevel == data.protectionLevel then
399 return self:renderIcon(data)
400 else
401 self.hasIncorrectProtectionIcon = true
402 end
403 end
404
405 -- Renders the first icon, either Canon or Legends, or nil if the continuity
406 -- couldn't be determined. This is equivalent to the previous {{Eraicon/canon}}
407 -- template.
408 function Eras:renderContinuityIcon()
409 -- First, find what continuity to use, if any.
410 local continuity, isUsingCategory
411 if self.continuityOverride == 'kaanon' or self:hasAnyOfIcons('can') then
412 continuity = 'canon'
413 if not self:hasAnyOfIcons('real') then
414 isUsingCategory = true
415 end
416 elseif self.continuityOverride == 'legends' or self:hasAnyOfIcons('leg') then
417 continuity = 'legends'
418 if not self:hasAnyOfIcons('real') then
419 isUsingCategory = true
420 end
421 elseif self.title.namespace == 0 then
422 if self:hasLegendsTitle() then
423 continuity = 'legends'
424 isUsingCategory = true
425 elseif self:hasCanonTitle() then
426 continuity = 'canon'
427 isUsingCategory = true
428 elseif self.legendsArticle then
429 continuity = 'canon'
430 isUsingCategory = true
431 elseif self.canonArticle then
432 continuity = 'legends'
433 isUsingCategory = true
434 elseif exists(self.title.text .. '/Legends') then
435 continuity = 'canon'
436 isUsingCategory = true
437 elseif exists(self.title.text .. '/Kaanon') and not isRedirect(self.title.text .. '/Kaanon') then
438 continuity = 'legends'
439 isUsingCategory = true
440 elseif self:hasAnyOfIcons('dotj', 'tor', 'thr', 'fotj', 'rote', 'aor',
441 'tnr', 'rofo', 'cnjo')
442 then
443 continuity = 'canon'
444 if self:hasAnyOfIcons('real') then
445 isUsingCategory = false
446 else
447 isUsingCategory = true
448 end
449 elseif self:hasAnyOfIcons('pre', 'btr', 'old', 'imp', 'reb', 'new',
450 'njo', 'lgc')
451 then
452 continuity = 'legends'
453 if self:hasAnyOfIcons('real') then
454 isUsingCategory = false
455 else
456 isUsingCategory = true
457 end
458 elseif self:hasAnyOfIcons('inf') then
459 continuity = 'legends'
460 isUsingCategory = false
461 elseif self:hasAnyOfIcons('real') then
462 isUsingCategory = false
463 else
464 continuity = 'canon'
465 isUsingCategory = true
466 end
467 end
468
469 -- Generate the icon data and make the icon.
470 if continuity == 'canon' then
471 local data = iconData['can']
472 if isUsingCategory then
473 data.category = 'Kaanonartikkelit'
474 end
475 return self:renderIcon(data)
476 elseif continuity == 'legends' then
477 local data = iconData['leg']
478 if isUsingCategory then
479 data.category = 'Legends-artikkelit'
480 end
481 return self:renderIcon(data)
482 end
483 end
484
485 -- Renders the icons that respond to a publishing era.
486 function Eras:renderPublishingIcons()
487 local ret = {}
488 local codes = {'dotj', 'tor', 'thr', 'fotj', 'rote', 'aor', 'tnr', 'rofo', 'cnjo',
489 'pre', 'btr', 'old', 'imp', 'reb', 'new', 'njo', 'lgc', 'inf'}
490 for _, code in ipairs(codes) do
491 local data = self:getIconData(code)
492 if data then
493 ret[#ret + 1] = self:renderIcon(data)
494 end
495 end
496 return table.concat(ret)
497 end
498
499 -- Renders other icons, e.g. featured article status and protection status.
500 function Eras:renderNonPublishingIcons()
501 local ret = {}
502 local codes = {'real', 'ss', 'ess', 'ha', 'eha', 'vkp'}
503 for _, code in ipairs(codes) do
504 local data = self:getIconData(code)
505 if data then
506 ret[#ret + 1] = self:renderIcon(data)
507 end
508 end
509 local protectionCodes = {'fprot', 'sprot', 'mprot', 'uprot'}
510 for _, code in ipairs(protectionCodes) do
511 local data = self:getIconData(code)
512 if data then
513 ret[#ret + 1] = self:renderProtectionIcon(data)
514 end
515 end
516 return table.concat(ret)
517 end
518
519 -- Render all the icons and eclose them in a surrounding div tag.
520 function Eras:renderIcons()
521 local icons = {}
522 icons[#icons + 1] = self:renderContinuityIcon()
523 icons[#icons + 1] = self:renderPublishingIcons()
524 icons[#icons + 1] = self:renderNonPublishingIcons()
525 icons = table.concat(icons)
526
527 local root = mw.getCurrentFrame():extensionTag{ name = "indicator", content = icons, args = { name = "eras"} }
528
529 return tostring(root)
530 end
531
532 -- Renders the Canon and Legends tabs for articles that are in both
533 -- continuities.
534 function Eras:renderCanonTab()
535 -- Tarkkailuluokat sivujen siirtoa varten
536 if self:hasCanonTitle() then
537 self:addCategory('Siirrettävät kaanonartikkelit')
538 elseif exists(self.title.text .. '/Kaanon') and not isRedirect(self.title.text .. '/Kaanon') then
539 self:addCategory('Siirrettävät Legends-artikkelit')
540 end
541
542 if self.isHidden or self.title.namespace ~= 0 then
543 -- Exit if we have been explicitly hidden or if we are not in the main
544 -- namespace.
545 return nil
546 end
547
548 -- Find the page type, canon title, and legends title.
549 local pageType, canonTitle, legendsTitle
550 if self.legendsArticle then
551 pageType = 'canon'
552 canonTitle = self.title.text
553 legendsTitle = self.legendsArticle
554 elseif self.canonArticle then
555 pageType = 'legends'
556 canonTitle = self.canonArticle
557 legendsTitle = self.title.text
558 elseif self:hasCanonTitle() then
559 pageType = 'canon'
560 canonTitle = self.title.text
561 legendsTitle = canonTitle:match('^(.*)/Kaanon$') or canonTitle
562 elseif self:hasLegendsTitle() then
563 pageType = 'legends'
564 legendsTitle = self.title.text
565 canonTitle = legendsTitle:match('^(.*)/Legends$') or legendsTitle
566 elseif exists(self.title.text .. '/Legends') then
567 pageType = 'canon'
568 legendsTitle = self.title.text .. '/Legends'
569 canonTitle = self.title.text
570 elseif exists(self.title.text .. '/Kaanon') and not isRedirect(self.title.text .. '/Kaanon') then
571 pageType = 'legends'
572 canonTitle = self.title.text .. '/Kaanon'
573 legendsTitle = self.title.text
574 else
575 -- Could not determine that the article has both a Canon and a Legends
576 -- version, so exit.
577 return nil
578 end
579
580 -- Add categories.
581 if pageType == 'canon' then
582 if self:hasCanonTitle() and exists(legendsTitle) == false then
583 self:addCategory('Kaanonartikkelit, joiden Legends-vastine puuttuu')
584 return nil
585 else
586 self:addCategory('Kaanonartikkelit, joista on vastine Legendsissä')
587 end
588 elseif pageType == 'legends' then
589 if self:hasLegendsTitle() and exists(canonTitle) == false then
590 self:addCategory('Legends-artikkelit, joiden kaanonvastine puuttuu')
591 return nil
592 else
593 self:addCategory('Legends-artikkelit, joista on vastine kaanonissa')
594 end
595 else
596 self:addCategory('Outliers')
597 end
598
599 -- Make the table root.
600 local root = mw.html.create('table')
601 root
602 :attr('id', 'canontab')
603 :css('text-align', 'center')
604 :css('padding', '0')
605 :css('margin', '0 0 5px 0')
606 :css('border-left', '0')
607 :css('border-right', '0')
608 :css('border-top', '0')
609 :css('border-bottom', '7px solid #002e54')
610 :css('border-spacing', '0')
611 :css('border-collapse', 'collapse')
612 :css('width', '100%')
613 :css('vertical-align', 'top')
614
615 local row = root:tag('tr')
616
617 -- This makes one Canon/Legends cell. Having this as a function rather than
618 -- doing it with chaining allows us to avoid putting the same code in twice.
619 local function makeCell(id, color, image, link, tooltip)
620 local cell = mw.html.create('td')
621 cell
622 :attr('id', id)
623 :css('padding', '5px 0 5px 0')
624 :css('background-color', color)
625 :css('line-height', '0.95em')
626 :css('font-size', '150%')
627 :css('font-weight', 'bold')
628 :css('width', '20px')
629 :css('vertical-align', 'top')
630 :css('border-top-left-radius', '5px')
631 :css('border-top-right-radius', '5px')
632 :wikitext(string.format(
633 ' [[Tiedosto:%s|link=%s|%s]]',
634 image, link, tooltip
635 ))
636 return cell
637 end
638
639 local foregroundColor = '#002e54'
640 local backgroundColor = '#d8e9fc'
641
642 -- Make the canon cell.
643 do
644 local id = 'canontab-canon'
645 local link = canonTitle
646 local color, image, tooltip
647 if pageType == 'canon' then
648 color = foregroundColor
649 image = 'Tab-canon-white-edit.png'
650 tooltip = 'Tämä on artikkelin kaanonversio.'
651 else
652 color = backgroundColor
653 image = 'Tab-canon-black-edit.png'
654 tooltip = "Paina tästä lukeaksesi artikkelin kaanonversiota."
655 end
656 row:node(makeCell(id, color, image, link, tooltip))
657 end
658
659 -- First separator cell
660 row:tag('td')
661 :attr('id', 'canontab-separator1')
662 :css('width', '3px')
663 :wikitext(' ')
664
665 -- Make the legends cell
666 do
667 local id = 'canontab-legends'
668 local link = legendsTitle
669 local color, image, tooltip
670 if pageType ~= 'canon' then -- is a Legends page
671 color = foregroundColor
672 image = 'Tab-legends-white.png'
673 tooltip = 'Tämä on artikkelin Legends-versio.'
674 else -- is a Canon page
675 color = backgroundColor
676 image = 'Tab-legends-black.png'
677 tooltip = "Paina tästä lukeaksesi artikkelin Legends-versiota."
678 end
679 row:node(makeCell(id, color, image, link, tooltip))
680 end
681
682 -- Second separator cell
683 row:tag('td')
684 :attr('id', 'canontab-separator2')
685 :css('width', '3000px')
686 :wikitext(' ')
687
688 return tostring(root)
689 end
690
691 -- Render all the categories that were specified using Eras:addCategory or with
692 -- category flags.
693 function Eras:renderCategories()
694 local fullPagename = self.title.prefixedText
695 if fullPagename == 'Malline:Eras' or fullPagename == 'Malline:Eraicon' then
696 -- Exit if we are on a blacklisted page.
697 return nil
698 end
699
700 local pagename = self.title.text
701
702 -- Lisää yhden luokan.
703 local function renderCategory(cat, sort)
704 return string.format(
705 '[[%s:%s|%s]]', 'Luokka', cat, sort or pagename
706 )
707 end
708
709 local ret = {}
710
711 -- Render categories from Eras:addCategory
712 for i, t in ipairs(self.categories) do
713 ret[i] = renderCategory(t.category, t.sortKey)
714 end
715
716 -- Render categories from category flags.
717 if self.hasBadParameter then
718 ret[#ret + 1] = renderCategory(
719 'Sivut, joissa on virheellisiä parametrejä mallineessa Eras'
720 )
721 end
722 if self.hasIncorrectProtectionIcon then
723 ret[#ret + 1] = renderCategory(
724 'Sivut, joissa on virheellisiä suojausmerkintöjä'
725 )
726 end
727
728 return table.concat(ret)
729 end
730
731 -- Lisää __NOTOC__ tarvittaessa
732 function Eras:renderNotoc()
733 if self.hideToc then
734 return '__NOTOC__'
735 end
736 return nil
737 end
738
739 -- This method is called when the tostring function is used on the Eras object.
740 -- (This works in a similar fashion to Eras.__index above.) It calls all the
741 -- top-level render methods and returns the final output.
742 function Eras:__tostring()
743 local ret = {}
744 ret[#ret + 1] = self:renderDisplayTitle()
745 ret[#ret + 1] = self:renderIcons()
746 ret[#ret + 1] = self:renderCanonTab()
747 ret[#ret + 1] = self:renderCategories()
748 ret[#ret + 1] = self:renderNotoc()
749 return table.concat(ret)
750 end
751
752 -------------------------------------------------------------------------------
753 -- Exports
754 -------------------------------------------------------------------------------
755
756 local p = {}
757
758 -- This function is the entry point from other Lua modules.
759 function p._main(args)
760 -- Define a function to call from pcall so that we can catch any errors
761 -- and display them to the user rather than the cryptic "Script error".
762 -- (It's not so cryptic if you click on it to see the error message, but
763 -- not so many users know to do that.)
764 local function getErasResult ()
765 local erasObj = Eras.new(args)
766 return tostring(erasObj)
767 end
768
769 -- Get the result. We only catch errors if debug mode is set to false.
770 local success, result
771 if DEBUG_MODE then
772 success = true
773 result = getErasResult()
774 else
775 success, result = pcall(getErasResult)
776 end
777
778 -- Return the result if there were no errors, and a formatted error message
779 -- if there were.
780 if success then
781 return result
782 else
783 return string.format(
784 '<strong class="error">[[Malline:Eras]]-virhe: %s.</strong>' ..
785 '[[Luokka:Sivut, joissa on virheellisiä parametrejä mallineessa Eras]]',
786 result -- this is the error message
787 )
788 end
789 end
790
791 -- This is the function accessed from wikitext. It must be accessed through
792 -- a template. The template should transclude only the text
793 -- "{{#invoke:Eras|main}}", and then when that template is used, any arguments
794 -- passed to it are magically sent through to the module.
795 function p.main(frame)
796 local args = {}
797 for k, v in pairs(frame:getParent().args) do
798 v = v:match('^%s*(.-)%s*$') -- trim whitespace
799 if v ~= '' then
800 args[k] = v
801 end
802 end
803 return p._main(args)
804 end
805
806 return p
807
808 -- </nowiki>
809 -- [[Luokka:Ulkoasumallineet|{{PAGENAME}}]]