Module:Transclude

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules

warning Warning:This page is shared between multiple wikis.
All changes to this page will be automatically copied to all wikis listed in the left side bar.
To avoid unnecessary page regeneration and server load, changes should be tested on the page's sandbox.

Usage

{{#invoke:Transclude|template_name}}

Code

-- <nowiki>
--------------------------------------------------------------------------------
-- Module that allows transcluding a template with all parent arguments.
-- Useful in `/i18n` template subpages that delegate to a `/layout` subpage.
--
-- @module transclude
-- @author [[User:ExE Boss]]
--------------------------------------------------------------------------------

require('strict')
local checkType = require('libraryUtil').checkType;

local p = {}
local INVALID_TITLES = {
	["."]	= true,
	[".."]	= true,
};

local function _ne(value)
	return value and value ~= ''
end

--------------------------------------------------------------------------------
-- Helper function that merges argument tables.
--
-- @function mergeArgs
-- @param {table} inArgs
-- @param {table} outArgs
--------------------------------------------------------------------------------
local function mergeArgs(inArgs, outArgs, opts)
	checkType("mergeArgs", 1, inArgs, "table");
	checkType("mergeArgs", 2, outArgs, "table");
	checkType("mergeArgs", 3, opts, "table", true);
	opts = opts or {}

	local ignoredParams = opts.ignoredParams;
	local ignoredPrefix = opts.ignoredPrefix;

	for name, value in pairs(inArgs) do
		if (type(name) == "string") then
			if not (
				(ignoredParams and ignoredParams[name] == true)
				or (ignoredPrefix and
					ignoredPrefix == name:sub(1, ignoredPrefix:len()))
			) then
				outArgs[name] = value;
			end
		else
			outArgs[name] = value;
		end
	end

	return outArgs;
end

-- Exported for testing:
p['#mergeArgs'] = mergeArgs;

local mt = {};

function mt.__index(_, name)
	if (
		type(name) ~= "string"
		or INVALID_TITLES[name]
		or mw.ustring.find(name, "#", nil, true)
	) then
		return nil;
	end

	local title = mw.title.new(name, "Template")
	if (not title) then
		return nil;
	end

	return function (frame)
		checkType('transclude["' .. name .. '"]', 1, frame, "table");
		local parentFrame = frame:getParent();

		local ignoredParams, ignoredPrefix;
		if _ne(frame.args["#ignoredParams"]) then
			ignoredParams = {};
            for m in mw.text.gsplit(frame.args["#ignoredParams"], '|', true) do
                ignoredParams[mw.text.trim(m)] = true;
            end
		end

		if _ne(frame.args['#ignoredPrefix']) then
			ignoredPrefix = frame.args['#ignoredPrefix'];
		end

		local args = {};
		if (parentFrame) then
			mergeArgs(parentFrame.args, args, {
				ignoredParams = ignoredParams,
				ignoredPrefix = ignoredPrefix,
			});
		end
		mergeArgs(frame.args, args, {
			ignoredPrefix = "#",
		});

		if (not title.exists) then
			return "[[:" .. title.fullText .. "]]";
		end

		return frame:expandTemplate{
			title = title,
			args = args,
		};
	end
end

return setmetatable(p, mt);