Jump to content

Module:Sandbox/Mr. Stradivarius/sandbox3

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius on tour (talk | contribs) at 04:43, 30 August 2013 (switch to an object-oriented approach). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

-- 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