From f0542e24790344a522a613e94d32ebc27f9aa77a Mon Sep 17 00:00:00 2001 From: RaNo Date: Thu, 1 Oct 2026 18:17:49 +0200 Subject: [PATCH] Fix mw.message plain() to substitute $N params in raw messages mw.message.newRawMessage() stores the message text in data.rawMessage and its params in data.params, but plain() returned data.keys, which newRawMessage never sets. So plain() returned nil for raw messages, and modules that build a message from a raw string plus params emitted the unsubstituted text with literal $1, $2 placeholders. This affected Module:Citation/CS1, whose substitute() falls back to the raw string when a message is falsy. Match the MediaWiki Messages API: substitute $N (one-based, multi-digit supported) with the corresponding param and leave unknown placeholders untouched. Keep returning data.keys for key-based messages as before. --- src/wikitextprocessor/lua/mw_message.lua | 8 ++++++- tests/test_lua.py | 30 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/wikitextprocessor/lua/mw_message.lua b/src/wikitextprocessor/lua/mw_message.lua index ece550d9..02b70952 100644 --- a/src/wikitextprocessor/lua/mw_message.lua +++ b/src/wikitextprocessor/lua/mw_message.lua @@ -127,7 +127,13 @@ local function makeMessage(options) function obj:plain() checkSelf(self, 'plain') - return data.keys + if not data.rawMessage then + return data.keys + end + -- https://www.mediawiki.org/wiki/Manual:Messages_API + return (data.rawMessage:gsub('$(%d+)', function(n) + return tostring(data.params[tonumber(n)] or '$' .. n) + end)) end function obj:exists() diff --git a/tests/test_lua.py b/tests/test_lua.py index e6f85b25..bc10417f 100644 --- a/tests/test_lua.py +++ b/tests/test_lua.py @@ -641,6 +641,36 @@ def test_el_strip_arg(self): "", ) + def test_mw_message_raw_message_params(self): + # Module:Citation/CS1 substitutes message parameters with mw.message + self.wtp.start_page("") + self.wtp.add_page( + "Module:test", + 828, + """local export = {} +function export.test(frame) + return mw.message.newRawMessage("$1 and $2 and $3", "one", "two"):plain() +end +return export""", + ) + self.assertEqual( + self.wtp.expand("{{#invoke:test|test}}"), "one and two and $3" + ) + + def test_mw_message_raw_message_double_digit_param(self): + self.wtp.start_page("") + self.wtp.add_page( + "Module:test", + 828, + """local export = {} +function export.test(frame) + return mw.message.newRawMessage("$10 $1", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", "ten"):plain() +end +return export""", + ) + self.assertEqual(self.wtp.expand("{{#invoke:test|test}}"), "ten one") + def test_mw_site_canonical_ns_key(self): # https://cs.wiktionary.org/wiki/Modul:Maintenance#L-193 # `mw.site.namespaces.Category.name`