Module:Sandbox/The JoTS/DynamicWelcome

-- Module:  DynamicWelcome (v1.1.0) -- Authors: "The JoTS" -- Allows for customizable welcome messages.

-- Update v1.1.0: Process "pipe trick"

-- See Help:Welcome tool for more info on the default welcome tool. -- To export this module for your wiki, use Special:Export and Special:Import.

--

-- [==[ Modules ]==] -- local getArgs = require("Dev:Arguments").getArgs; local yesno = require "Dev:Yesno"; local custom,messages = pcall(function return mw.loadData "Module:DynamicWelcome/msg"; end);

-- user failiure error if (not custom) and messages:match("^%%") then error(messages:sub(2)); end;

--messages = custom and messages or mw.loadData "Dev:DynamicWelcome/default"; -- default messages -- properly implement default messages at a later time

-- [==[ Meta Functions ]==] -- -- Passes an argument table to a function, and post-processes returned text local arg_wrap = function(func) return function(frame) return frame:preprocess( func(getArgs(frame)) ); end; end;

-- Returns the namespace of a given page name. ...Or removes the namespace from a given page name. local function namespaceOp(pageName, gsub) return string[gsub and "gsub" or "match"](pageName, "^(.+):", gsub and "" or nil); end

-- Dynamic processing of the "pipe trick," instead of at page save time. (frame:preprocess does not process the pipe trick, apparently) -- See WP:Help:Pipe trick for more details local function processPipeTrick(txt) -- the pipe trick involving the comma is NOT implemented return txt:gsub("%[%[([^|]+)|%]%]", function(page)       -- get page name        local name = page            :gsub ("^[%w%s_]+:", '')            :match "[%w%s_]+"            :match "^%s*(.-)%s*$";        -- return formatted link        return "' .. name .. "";    end) end

-- Validate input local function validate(provided, options) return options[provided]; end

-- [==[ Module Functions ]==] -- -- Constants local MODES = { ["message-wall"] = true, ["message"] = true }; local VAR_ENUM = { -- Implement custom enum for vars page       = 1, greeter_talk = 2, greeter_sig = 3, welcomed    = 4 } local SETUP_CONST = { ADMIN = true, MODE = true, ANON = true };

local function _greet(vargs) -- Set Enumerator local args = setmetatable({}, { __index = function(t, key)       -- metatable that indexes another table... that essentially is just another metatable >_<        return vargs[VAR_ENUM[key] or key];    end }) assert((not args.mode) or validate(args.mode, MODES), "An invalid mode was provided"); -- error, input validation args.mode = (type(args.mode) ~= "string" and "message-wall" or args.mode); -- default mode is 'message wall' args.anon = yesno(args.anon) and "anon" or "user"; -- default mode is 'user' local dict = messages[args.mode][args.anon]; -- selected root dictionary -- Selected greeter dictionary ("Wikia" is fallback) local gDict = (not dict) and error( "The \"" .. args.anon .. "\" dictionary does not exist" ) or dict[namespaceOp(args.greeter_talk, true)] or dict.Wikia or error("The default greeter dictionary,\"Wikia\", does not exist"); local entry = gDict[namespaceOp(args.page)] or gDict.DEFAULT or error("The default entry does not exist"); -- Return formatted entry return processPipeTrick( entry:gsub("%$(%d)", function(var) -- Substitute variable numbers w/ value return args[tonumber(var)] or var; end) ) end

local greet = arg_wrap( _greet );

local function wizard(admin, mode, globals) -- errors assert(globals.ADMIN == admin, "%Admin mismatch: " .. globals.ADMIN .. " x " .. admin); assert(globals.MODE == mode, "%Mode mismatch: " .. globals.MODE .. " x " .. mode); assert(validate(mode, MODES), "%An invalid mode was provided: " .. mode); assert(type(globals.ANON) == "boolean", "%Global \"ANON\" was not initialized or is not a boolean") local frm = globals.__DYNAWELC__ or {}; -- formatted table local anon = globals.ANON and "anon" or "user"; -- setup globals.__DYNAWELC__ = frm; frm[mode] = frm[mode] or {}; frm[mode][anon] = frm[mode][anon] or {}; frm[mode][anon][admin] = frm[mode][anon][admin] or {}; -- create entry for k,v in pairs(globals) do       if k:match("^(%u[%w_]+)$") and (not validate(k, SETUP_CONST)) then globals[k] = nil; -- clear frm[mode][anon][admin][k:gsub('_',' ')] = v;       end end

return frm; end

--- Module interface --- return { -- template functions greet  = greet; welcome = greet; main   = greet; -- metamodule functions wizard = wizard; format = wizard; prep  = wizard; setup = wizard; }