ಮಾಡ್ಯೂಲ್:Infobox/sandbox
From Wikipedia, the free encyclopedia
-- This module implements
local checkType = require('libraryUtil').checkType local CONFIG_MODULE = 'Module:Infobox/config'
-- Helper functions
local function nilFunc () -- To avoid using a different anonymous function every time an argument -- uses the Infobox.rowArgDefaults metatable. return nil end
local function trueFunc () -- To avoid using a different anonymous function for every data row. return true end
local function makeCategory(cat) if cat then return string.format('', cat) end end
-- Infobox class
local Infobox = {} Infobox.__index = Infobox Infobox.rowArgDefaults = {__index = function (t, key) t[key] = nilFunc return nilFunc end}
function Infobox.new(args, cfg, title) local self = setmetatable({}, Infobox) self.cfg = cfg self.title = title self.root = mw.html.create('table')
-- Set the args. We pass the args around as functions, so that we can delay -- argument expansion until the last minute. This enables us to expand the -- arguments in the correct order, and only when necessary. This is -- important for [1] tags, as otherwise:
-- 1. A
- ...
tag at the bottom of an infobox might get expanded
-- before [1] tags higher up in an infobox, and the reference -- doesn't appear where it should; or -- 2. [2] tags in a label cell can be expanded, but not -- displayed in the infobox due to the lack of a corresponding data -- cell argument. This causes a "phantom reference" where the citation
-- is visible in the
- ...
- ...
tag output, but there is no link to
-- it anywhere in the article. self.args = setmetatable({}, {__index = function (t, key) local val local function expandThisArg () if val == false then return nil elseif val then return val else val = args[key] if val == then val = false return nil elseif val == false then return nil else return val end end end t[key] = expandThisArg return expandThisArg end})
-- Special case for italic title, which can be different depending on -- whether it is blank or absent. self.args['italic title'] = function () return args['italic title'] end
self.hasDataCell = false -- Track data cell usage.
return self end
function Infobox:renderTitle() local args = self.args if not args.title() then return end
self.root :tag('caption') :addClass(args.titleclass()) :cssText(args.titlestyle()) :wikitext(args.title()) end
function Infobox:renderAboveRow() local args = self.args if not args.above() then return end
self.root :tag('tr') :tag('th') :attr('colspan', 2) :addClass(args.aboveclass()) :css('text-align', 'center') :css('font-size', '125%') :css('font-weight', 'bold') :cssText(args.abovestyle()) :wikitext(args.above()) end
function Infobox:renderBelowRow() local args = self.args if not args.below() then return end
self.root :tag('tr') :tag('td') :attr('colspan', '2') :addClass(args.belowclass()) :css('text-align', 'center') :cssText(args.belowstyle()) :newline() :wikitext(args.below()) end
function Infobox:addRow(rowArgs) -- Adds a row to the infobox, with either a header cell -- or a label/data cell combination. setmetatable(rowArgs, Infobox.rowArgDefaults) -- Set a default function local hasContent = false -- Tracks whether we have rendered anything. local args = self.args local header = rowArgs.header() if header then hasContent = true self.root :tag('tr') :addClass(rowArgs.rowclass()) :cssText(rowArgs.rowstyle()) :attr('id', rowArgs.rowid()) :tag('th') :attr('colspan', 2) :attr('id', rowArgs.headerid()) :addClass(rowArgs.class()) :addClass(args.headerclass()) :css('text-align', 'center') :cssText(args.headerstyle()) :wikitext(header) else local data = rowArgs.data() if data then hasContent = true
-- Track data cells, but not images or subheaders, for use in -- generating tracking categories. if rowArgs.isDataCellCheck() then self.hasDataCell = true end
local row = self.root:tag('tr') row:addClass(rowArgs.rowclass()) row:cssText(rowArgs.rowstyle()) row:attr('id', rowArgs.rowid()) local label = rowArgs.label() if label then row :tag('th') :attr('scope', 'row') :attr('id', rowArgs.labelid()) :css('text-align', 'left') :cssText(args.labelstyle()) :wikitext(label) :done() end
local dataCell = row:tag('td') if not label then dataCell :attr('colspan', 2) :css('text-align', 'center') end dataCell :attr('id', rowArgs.dataid()) :addClass(rowArgs.class()) :cssText(rowArgs.datastyle()) :newline() :wikitext(data) end end return hasContent end
function Infobox:renderNumberedRows(rowArgMaker, gap) -- Renders numbered rows using Infobox:addRow. rowArgMaker is a function -- that makes the table of rowArgs to be used by addRow. It takes the row -- number as input. This method will continue to try and add rows until -- the number of sequential blank rows is greater than the number specified -- in gap. local iRow, iGap = 0, 0 while iGap < gap do iRow = iRow + 1 iGap = iGap + 1 if self:addRow(rowArgMaker(iRow)) then iGap = 0 end end end
function Infobox:renderSubheaders() local args = self.args if args.subheader() then args.subheader1 = args.subheader end if args.subheaderrowclass() then args.subheaderrowclass1 = args.subheaderrowclass end return self:renderNumberedRows( function (i) i = tostring(i) return { data = args['subheader' .. i], datastyle = function () return args.subheaderstyle() or args['subheaderstyle' .. i]() end, class = args.subheaderclass, rowclass = args['subheaderrowclass' .. i] } end, 2 ) end
function Infobox:renderImages() local args = self.args if args.image() then args.image1 = args.image end if args.caption() then args.caption1 = args.caption end return self:renderNumberedRows( function (i) i = tostring(i) return { data = function () local image = args['image' .. i]() if image then local data = mw.html.create():wikitext(image) local caption = args['caption' .. i]() if caption then data :tag('div') :cssText(args.captionstyle()) :wikitext(caption) end return tostring(data) end end, datastyle = args.imagestyle, class = args.imageclass, rowclass = args['imagerowclass' .. i] } end, 3 ) end
function Infobox:renderContentRows() local args = self.args return self:renderNumberedRows( function (i) i = tostring(i) return { -- Tell addRow to set self.hasDataCells to true if it finds a -- data cell argument. isDataCellCheck = trueFunc,
header = args['header' .. i], label = args['label' .. i], data = args['data' .. i], datastyle = args.datastyle, class = args['class' .. i], rowclass = args['rowclass' .. i], rowstyle = args['rowstyle' .. i], dataid = args['dataid' .. i], labelid = args['labelid' .. i], headerid = args['headerid' .. i], rowid = args['rowid' .. i] } end, 10, 'hasContentRows' ) end
function Infobox:renderNavBar() local args = self.args if not args.name() then return end
self.root :tag('tr') :tag('td') :attr('colspan', '2') :css('text-align', 'right') :wikitext(mw.getCurrentFrame():expandTemplate({ title = 'navbar', args = { args.name(), mini = 1 } })) end
function Infobox:renderItalicTitle() local args = self.args local italicTitle = args['italic title']() and mw.ustring.lower(args['italic title']()) if italicTitle == or italicTitle == 'force' or italicTitle == 'yes' then self.root:wikitext(mw.getCurrentFrame():expandTemplate({title = 'italic title'})) end end
function Infobox:renderTrackingCategories() local args = self.args local cfg = self.cfg if args.decat() ~= 'yes' then if not self.hasContentRows and self.title.namespace == 0 then self.root:wikitext(makeCategory(cfg['category-no-data-row'])) end if args.child() == 'yes' and args.title() then self.root:wikitext(makeCategory(cfg['category-embedded-title'])) end end end
function Infobox:__tostring() -- Specify the overall layout of the infobox, with special settings -- if the infobox is used as a 'child' inside another infobox. local args = self.args if args.child() ~= 'yes' then self.root :addClass('infobox') :addClass(args.bodyclass())
if args.subbox() == 'yes' then self.root :css('padding', '0') :css('border', 'none') :css('margin', '-3px') :css('width', 'auto') :css('min-width', '100%') :css('font-size', '100%') :css('clear', 'none') :css('float', 'none') :css('background-color', 'transparent') else self.root :css('width', '22em') end self.root :cssText(args.bodystyle())
self:renderTitle() self:renderAboveRow() else self.root = mw.html.create()
self.root :wikitext(args.title()) end
self:renderSubheaders() self:renderImages() self:renderContentRows() self:renderBelowRow() self:renderNavBar() self:renderItalicTitle() self:renderTrackingCategories()
return tostring(self.root) end
-- Exports
local p = {}
function p._infobox(args, cfg, title) checkType('_infobox', 1, args, 'table') checkType('_infobox', 2, cfg, 'table', true) cfg = cfg or mw.loadData(CONFIG_MODULE) title = title or mw.title.getCurrentTitle() return tostring(Infobox.new(args, cfg, title)) end
function p.infobox(frame, cfg) cfg = cfg or mw.loadData(CONFIG_MODULE) local args if cfg.wrapper then local parent = frame:getParent() local parentTitle = parent:getTitle() local wrapper = mw.title.new(cfg.wrapper).prefixedText if parentTitle == wrapper or parentTitle == wrapper .. cfg['wrapper-sandbox-suffix'] then args = parent.args end end args = args or frame.args return p._infobox(args, cfg) end
return p