Skip to content

Widget3 incompatible with WidgetFactory when using defaultProps #7476

@ElectricalBoy

Description

@ElectricalBoy

-- Apply DefaultProps via lightweight metatable
-- Only shallow default props allowed
if self.defaultProps then
setmetatable(props, { __index = self.defaultProps })
end

ComponentMT.__call assumes that props will always be a normal table and sets (lightweight) metatable for quickly accessing defaultProps. This assumption is not true when widget3 is called via WidgetFactory.fromTemplate:

---@param args {widget: string, children: Renderable|Renderable[], [any]:any}
---@return Widget
function WidgetFactory.fromTemplate(args)
local widgetClass = args.widget
args.widget = nil
args.children = type(args.children) == 'table' and args.children or {args.children}
local WidgetClass = Lua.import('Module:Widget/' .. widgetClass)
return WidgetClass(args)
end
return Class.export(WidgetFactory, {exports = {'fromTemplate'}})

This is because Module:Arguments does not allow direct access to args and hides it behind a metatable, as shown in the code snippet (copied from L190-L197) below:

	--[[
	-- Set up the args, metaArgs and nilArgs tables. args will be the one
	-- accessed from functions, and metaArgs will hold the actual arguments. Nil
	-- arguments are memoized in nilArgs, and the metatable connects all of them
	-- together.
	--]]
	local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
	setmetatable(args, metatable)

Thus, setting the metatable in ComponentMT.__call unsets the metatable set by Arguments.getArgs and results as losing all wikicode arguments being passed in.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions