Difference between revisions of "Module:User:Mr. Stradivarius/sandbox3"
Jump to navigation
Jump to search
blackwiki>Mr. Stradivarius (WikiProject banner code) |
blackwiki>Mr. Stradivarius on tour (switch to an object-oriented approach) |
||
| Line 1: | Line 1: | ||
| + | -- TODO: | ||
| + | -- define self.page | ||
| + | |||
local htmlBuilder = require( 'Module:HtmlBuilder' ) | local htmlBuilder = require( 'Module:HtmlBuilder' ) | ||
| + | ---------------------------------------------------------- | ||
| + | -- Define constants | ||
| + | ---------------------------------------------------------- | ||
| + | |||
| + | local currentTitleObject = mw.title.getCurrentTitle() | ||
| + | |||
| + | ---------------------------------------------------------- | ||
| + | -- Helper functions | ||
| + | ---------------------------------------------------------- | ||
| − | -- | + | -- Makes a simple function that raises an error if the dot syntax is used with methods. |
| − | local function | + | -- It is not 100% reliable, but will catch the majority of cases, and works with inheritance. |
| − | if type( | + | local function makeCheckSelfFunction( libraryName, varName, selfObjDesc ) |
| − | + | return function( self, method ) | |
| + | if type( self ) ~= 'table' or type( self.new ) ~= 'function' then | ||
| + | error( mw.ustring.format( | ||
| + | '%s: invalid %s. Did you call %s with a dot instead of a colon, i.e. %s.%s() instead of %s:%s()?', | ||
| + | libraryName, selfObjDesc, method, varName, method, varName, method | ||
| + | ), 3 ) | ||
| + | end | ||
end | end | ||
| − | + | end | |
| − | + | ||
| − | + | -- Checks to see if a given variable is a non-blank string. Returns the string if true, | |
| − | + | -- and returns false if not. | |
| − | + | local function checkString( s ) | |
| − | if | + | if type( s ) == 'string' and s ~= '' then |
| − | + | return s | |
| − | + | else | |
| + | return false | ||
end | end | ||
end | end | ||
| − | local function | + | -- Checks to see if a given variable is an object of some kind. Returns the object if true, |
| − | + | -- and returns false if not. | |
| − | + | local function checkObject( obj ) | |
| + | if type( obj ) == 'table' and type( obj.new ) == 'function' then | ||
| + | return obj | ||
| + | else | ||
return false | return false | ||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
end | end | ||
| + | |||
| + | ---------------------------------------------------------- | ||
| + | -- Define the banner class | ||
| + | ---------------------------------------------------------- | ||
local banner = {} | local banner = {} | ||
banner.__index = banner | banner.__index = banner | ||
| + | local checkSelfBanner = makeCheckSelfFunction( 'Module:WikiProjectBanner', 'banner', 'banner object' ) | ||
| − | function banner | + | function banner:new( init ) |
| − | + | init = type( init ) == 'table' and init or {} | |
local obj = {} | local obj = {} | ||
| − | function | + | |
| − | + | obj.objectName = init.objectName | |
| + | if not obj.objectName then | ||
| + | error( [[No object name specified. Please use "banner:new{ objectName = 'myObject' }".]], 2 ) | ||
| + | end | ||
| + | |||
| + | -- Set the project name and exit if its value is absent or invalid. | ||
| + | obj.project = init.project | ||
| + | if type( obj.project ) ~= 'string' or obj.project == '' then return end | ||
| + | |||
| + | -- Set the index metamethod and the metatable. | ||
| + | self.__index = self | ||
| + | return setmetatable( obj, self ) | ||
| + | end | ||
| + | |||
| + | function banner:setImage() | ||
| + | checkSelfBanner( self, 'setImage' ) | ||
| + | end | ||
| + | |||
| + | -- Adds one category to the banner's "categories" table. | ||
| + | function banner:addCategory( category ) | ||
| + | category = checkString( category ) | ||
| + | if category then | ||
| + | self.categories = self.categories or {} | ||
| + | table.insert( self.categories, category ) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | -- Adds all categories in a "categories" array to the banner's "categories" table. | ||
| + | function banner:addCategories( categoryTable ) | ||
| + | if type( categoryTable ) == 'table' then | ||
| + | for i, category in ipairs( rowObject.categories ) do | ||
| + | self:addCategory( category ) | ||
| + | end | ||
end | end | ||
| − | if | + | end |
| − | + | ||
| + | -- Returns a string of category links for the categories in obj.categories. | ||
| + | function banner:exportCategories() | ||
| + | if type( self.categories ) == 'table' then | ||
| + | local ret = {} | ||
| + | for i, category in ipairs( self.categories ) do | ||
| + | category = checkString( category ) | ||
| + | if category then | ||
| + | table.insert( ret, mw.ustring.format( | ||
| + | '[[Category:%s|%s]]', | ||
| + | category, | ||
| + | type( self.page ) == 'string' and self.page or currentTitleObject.text | ||
| + | ) ) | ||
| + | end | ||
| + | end | ||
| + | return table.concat( ret ) | ||
end | end | ||
| − | + | return '' | |
| − | + | end | |
| − | + | ||
| − | + | -- Adds a row object to the banners "rows" table, and adds the row object's categories | |
| − | + | -- to the banners "categories" table. Categories are deleted from the row object after | |
| − | + | -- they have been transferred. | |
| − | + | function banner:addRow( rowObject ) | |
| − | if | + | checkSelfBanner( self, 'addRow' ) |
| − | + | self.rows = self.rows or {} | |
| − | + | rowObject = checkObject( rowObject ) | |
| − | + | if rowObject then | |
| − | + | self:addCategories( rowObject.categories ) | |
| − | + | rowObject.categories = nil -- Erase the categories from the row object to make sure we don't add the same categories twice. | |
| + | table.insert( self.rows, rowObject ) | ||
end | end | ||
| − | + | end | |
| − | + | ||
| − | if | + | function banner:exportRows() |
| − | + | local ret = {} | |
| − | + | if type( self.rows ) == 'table' then | |
| − | + | for i, rowObject in ipairs( self.rows ) do | |
| − | + | rowObject = checkObject( rowObject ) | |
| − | + | if rowObject then | |
| − | + | table.insert( ret, rowObject:export() ) | |
| − | + | end | |
| − | |||
| − | |||
end | end | ||
end | end | ||
| − | obj. | + | return table.concat( ret ) |
| − | setmetatable( obj, | + | end |
| − | return | + | |
| + | function banner:export( templateArgs ) | ||
| + | checkSelfBanner( self, 'export' ) | ||
| + | end | ||
| + | |||
| + | ---------------------------------------------------------- | ||
| + | -- Define the row class | ||
| + | ---------------------------------------------------------- | ||
| + | |||
| + | local row = {} | ||
| + | row.__index = row | ||
| + | local checkSelfRow = makeCheckSelfFunction( 'Module:WikiProjectBanner', 'row', 'row object' ) | ||
| + | |||
| + | function row:new( init ) | ||
| + | init = type( init ) == 'table' and init or {} | ||
| + | local obj = {} | ||
| + | |||
| + | -- Set the index metamethod and the metatable. | ||
| + | self.__index = self | ||
| + | return setmetatable( obj, self ) | ||
| + | end | ||
| + | |||
| + | function row:addCategory( category ) | ||
| + | checkSelfRow( self, 'addCategory' ) | ||
| + | if type( category ) == 'string' and category ~= '' then | ||
| + | self.categories = self.categories or {} | ||
| + | table.insert( self.categories, category ) | ||
| + | end | ||
| + | end | ||
| + | |||
| + | function row:export() | ||
| + | checkSelfRow( self, 'export' ) | ||
| + | |||
| + | -- Get the result of the icon and content export functions, and check the results. | ||
| + | local rowIconOutput = type( self.exportRowIcon ) == 'function' and self:exportRowIcon() | ||
| + | rowIconOutput = checkString( rowIconOutput ) | ||
| + | local rowContentOutput = type( self.exportRowContent ) == 'function' and self:exportRowContent() | ||
| + | rowContentOutput = checkString( rowContentOutput ) | ||
| + | |||
| + | -- Export the row html. | ||
| + | local ret = htmlBuilder.create() | ||
| + | if rowIconOutput and rowContentOutput then | ||
| + | ret | ||
| + | .tag( 'tr' ) | ||
| + | .tag( 'td' ) | ||
| + | .wikitext( rowIconOutput ) | ||
| + | .done() | ||
| + | .tag( 'td' ) | ||
| + | .attr( 'colspan', '2' ) | ||
| + | .wikitext( rowContentOutput ) | ||
| + | elseif rowContentOutput and not rowIconOutput then | ||
| + | ret | ||
| + | .tag( 'tr' ) | ||
| + | .tag( 'td' ) | ||
| + | .attr( 'colspan', '3' ) | ||
| + | .wikitext( rowContentOutput ) | ||
| + | end | ||
| + | return tostring( ret ) | ||
end | end | ||
| + | |||
| + | ---------------------------------------------------------- | ||
| + | -- Define the taskForce class | ||
| + | ---------------------------------------------------------- | ||
| + | |||
| + | local taskForce = row:new() | ||
| + | |||
| + | ----------------------------------------------------------------- | ||
| + | -- Export objects and functions to be used from other modules | ||
| + | ----------------------------------------------------------------- | ||
local p = {} | local p = {} | ||
| − | function p. | + | p.banner = banner |
| − | local | + | p.row = row |
| − | return | + | p.makeCheckSelfFunction = makeCheckSelfFunction |
| + | |||
| + | ----------------------------------------------------------------- | ||
| + | -- Testing area | ||
| + | ----------------------------------------------------------------- | ||
| + | |||
| + | function p.test( frame ) | ||
| + | local myRow = row:new() | ||
| + | return row:export() | ||
end | end | ||
| + | |||
return p | return p | ||
Revision as of 04:43, 30 August 2013
| This module is rated as pre-alpha. It is unfinished, and may or may not be in active development. It should not be used from article namespace pages. Modules remain pre-alpha until the original editor (or someone who takes one over if it is abandoned for some time) is satisfied with the basic structure. |
Usage
Template:Missing documentation
{{#invoke:User:Mr. Stradivarius|function_name}}
-- TODO:
-- define self.page
local htmlBuilder = require( 'Module:HtmlBuilder' )
----------------------------------------------------------
-- Define constants
----------------------------------------------------------
local currentTitleObject = mw.title.getCurrentTitle()
----------------------------------------------------------
-- Helper functions
----------------------------------------------------------
-- Makes a simple function that raises an error if the dot syntax is used with methods.
-- It is not 100% reliable, but will catch the majority of cases, and works with inheritance.
local function makeCheckSelfFunction( libraryName, varName, selfObjDesc )
return function( self, method )
if type( self ) ~= 'table' or type( self.new ) ~= 'function' then
error( mw.ustring.format(
'%s: invalid %s. Did you call %s with a dot instead of a colon, i.e. %s.%s() instead of %s:%s()?',
libraryName, selfObjDesc, method, varName, method, varName, method
), 3 )
end
end
end
-- Checks to see if a given variable is a non-blank string. Returns the string if true,
-- and returns false if not.
local function checkString( s )
if type( s ) == 'string' and s ~= '' then
return s
else
return false
end
end
-- Checks to see if a given variable is an object of some kind. Returns the object if true,
-- and returns false if not.
local function checkObject( obj )
if type( obj ) == 'table' and type( obj.new ) == 'function' then
return obj
else
return false
end
end
----------------------------------------------------------
-- Define the banner class
----------------------------------------------------------
local banner = {}
banner.__index = banner
local checkSelfBanner = makeCheckSelfFunction( 'Module:WikiProjectBanner', 'banner', 'banner object' )
function banner:new( init )
init = type( init ) == 'table' and init or {}
local obj = {}
obj.objectName = init.objectName
if not obj.objectName then
error( [[No object name specified. Please use "banner:new{ objectName = 'myObject' }".]], 2 )
end
-- Set the project name and exit if its value is absent or invalid.
obj.project = init.project
if type( obj.project ) ~= 'string' or obj.project == '' then return end
-- Set the index metamethod and the metatable.
self.__index = self
return setmetatable( obj, self )
end
function banner:setImage()
checkSelfBanner( self, 'setImage' )
end
-- Adds one category to the banner's "categories" table.
function banner:addCategory( category )
category = checkString( category )
if category then
self.categories = self.categories or {}
table.insert( self.categories, category )
end
end
-- Adds all categories in a "categories" array to the banner's "categories" table.
function banner:addCategories( categoryTable )
if type( categoryTable ) == 'table' then
for i, category in ipairs( rowObject.categories ) do
self:addCategory( category )
end
end
end
-- Returns a string of category links for the categories in obj.categories.
function banner:exportCategories()
if type( self.categories ) == 'table' then
local ret = {}
for i, category in ipairs( self.categories ) do
category = checkString( category )
if category then
table.insert( ret, mw.ustring.format(
'[[Category:%s|%s]]',
category,
type( self.page ) == 'string' and self.page or currentTitleObject.text
) )
end
end
return table.concat( ret )
end
return ''
end
-- Adds a row object to the banners "rows" table, and adds the row object's categories
-- to the banners "categories" table. Categories are deleted from the row object after
-- they have been transferred.
function banner:addRow( rowObject )
checkSelfBanner( self, 'addRow' )
self.rows = self.rows or {}
rowObject = checkObject( rowObject )
if rowObject then
self:addCategories( rowObject.categories )
rowObject.categories = nil -- Erase the categories from the row object to make sure we don't add the same categories twice.
table.insert( self.rows, rowObject )
end
end
function banner:exportRows()
local ret = {}
if type( self.rows ) == 'table' then
for i, rowObject in ipairs( self.rows ) do
rowObject = checkObject( rowObject )
if rowObject then
table.insert( ret, rowObject:export() )
end
end
end
return table.concat( ret )
end
function banner:export( templateArgs )
checkSelfBanner( self, 'export' )
end
----------------------------------------------------------
-- Define the row class
----------------------------------------------------------
local row = {}
row.__index = row
local checkSelfRow = makeCheckSelfFunction( 'Module:WikiProjectBanner', 'row', 'row object' )
function row:new( init )
init = type( init ) == 'table' and init or {}
local obj = {}
-- Set the index metamethod and the metatable.
self.__index = self
return setmetatable( obj, self )
end
function row:addCategory( category )
checkSelfRow( self, 'addCategory' )
if type( category ) == 'string' and category ~= '' then
self.categories = self.categories or {}
table.insert( self.categories, category )
end
end
function row:export()
checkSelfRow( self, 'export' )
-- Get the result of the icon and content export functions, and check the results.
local rowIconOutput = type( self.exportRowIcon ) == 'function' and self:exportRowIcon()
rowIconOutput = checkString( rowIconOutput )
local rowContentOutput = type( self.exportRowContent ) == 'function' and self:exportRowContent()
rowContentOutput = checkString( rowContentOutput )
-- Export the row html.
local ret = htmlBuilder.create()
if rowIconOutput and rowContentOutput then
ret
.tag( 'tr' )
.tag( 'td' )
.wikitext( rowIconOutput )
.done()
.tag( 'td' )
.attr( 'colspan', '2' )
.wikitext( rowContentOutput )
elseif rowContentOutput and not rowIconOutput then
ret
.tag( 'tr' )
.tag( 'td' )
.attr( 'colspan', '3' )
.wikitext( rowContentOutput )
end
return tostring( ret )
end
----------------------------------------------------------
-- Define the taskForce class
----------------------------------------------------------
local taskForce = row:new()
-----------------------------------------------------------------
-- Export objects and functions to be used from other modules
-----------------------------------------------------------------
local p = {}
p.banner = banner
p.row = row
p.makeCheckSelfFunction = makeCheckSelfFunction
-----------------------------------------------------------------
-- Testing area
-----------------------------------------------------------------
function p.test( frame )
local myRow = row:new()
return row:export()
end
return p