Module:WikitextProcessor: Difference between revisions
Appearance
// via Wikitext Extension for VSCode |
// via Wikitext Extension for VSCode |
||
| Line 120: | Line 120: | ||
pattern = '%[%[([^#|%]]+)|([^%]]+)%]%]', | pattern = '%[%[([^#|%]]+)|([^%]]+)%]%]', | ||
processor = function(pageName, text, errorContext) | processor = function(pageName, text, errorContext) | ||
-- Step 1: Generate URL | |||
local success1, pageUrl = pcall(function() | local success1, pageUrl = pcall(function() | ||
return tostring(mw.uri.fullUrl((pageName:gsub(' ', '_')))) | return tostring(mw.uri.fullUrl((pageName:gsub(' ', '_')))) | ||
| Line 125: | Line 126: | ||
if not success1 then | if not success1 then | ||
return handleProcessingError(errorContext, 'urlFailedPattern2', | |||
'Error: ' .. tostring(pageUrl), | |||
'[[' .. pageName .. '|' .. text .. ']]') | |||
end | end | ||
-- Step 2: Encode text | |||
local textStr = type(text) == "string" and text or tostring(text) | |||
local success2, encodedText = pcall(mw.text.encode, textStr) | |||
if not success2 then | if not success2 then | ||
return handleProcessingError(errorContext, 'encodeFailedPattern2', | |||
'Error: ' .. tostring(encodedText), | |||
'[[' .. pageName .. '|' .. text .. ']]') | |||
end | end | ||
local success3, result = pcall( | -- Step 3: Format HTML | ||
local success3, result = pcall(string.format, '<a href="%s">%s</a>', pageUrl, encodedText) | |||
if not success3 then | if not success3 then | ||
return handleProcessingError(errorContext, 'formatFailedPattern2', | |||
'Error: ' .. tostring(result), | |||
'[[' .. pageName .. '|' .. text .. ']]') | |||
end | end | ||
Revision as of 21:16, 1 August 2025
Documentation for this module may be created at Module:WikitextProcessor/doc
-- Module:WikitextProcessor
-- Processes JSON content with wikitext formatting for frontend display
-- Handles placeholder replacement, wiki link conversion to HTML, and content normalization
local p = {}
-- Dependencies
local ErrorHandling = require('Module:ErrorHandling')
-- Helper function to determine appropriate context name for error reporting
local function getContextName(errorContext)
if not errorContext then
return 'wikitextProcessor'
end
-- Check if this is a campaign context (backward compatibility)
if errorContext.contextType == 'T-Campaign' or
(errorContext.errors and errorContext.errors.campaignBanner) then
return 'campaignBanner' -- Maintain existing behavior
end
-- Default to generic context for new uses
return errorContext.contextName or 'wikitextProcessor'
end
-- Error message mapping for backward compatibility
local ERROR_MESSAGES = {
-- Campaign-specific messages (preserve existing)
campaignBanner = {
urlFailed = 'mw.uri.fullUrl failed for page link',
urlFailedPattern2 = 'Pattern 2 mw.uri.fullUrl failed',
urlFailedPattern3 = 'Pattern 3 mw.uri.anchorEncode failed',
encodeFailed = 'mw.text.encode failed for page link',
encodeFailedPattern2 = 'Pattern 2 mw.text.encode failed',
encodeFailedPattern3 = 'Pattern 3 mw.text.encode failed',
formatFailed = 'string.format failed for page link',
formatFailedPattern2 = 'Pattern 2 string.format failed',
formatFailedPattern3 = 'Pattern 3 string.format failed'
},
-- Generic messages for new contexts
wikitextProcessor = {
urlFailed = 'URL generation failed for wiki link',
urlFailedPattern2 = 'URL generation failed for wiki link',
urlFailedPattern3 = 'Anchor encoding failed for wiki link',
encodeFailed = 'Text encoding failed for wiki link',
encodeFailedPattern2 = 'Text encoding failed for wiki link',
encodeFailedPattern3 = 'Text encoding failed for wiki link',
formatFailed = 'HTML formatting failed for wiki link',
formatFailedPattern2 = 'HTML formatting failed for wiki link',
formatFailedPattern3 = 'HTML formatting failed for wiki link'
}
}
-- Get appropriate error message based on context
local function getErrorMessage(contextName, messageType)
local messages = ERROR_MESSAGES[contextName] or ERROR_MESSAGES.wikitextProcessor
return messages[messageType] or messages.urlFailed
end
-- Unified error handling that preserves existing T-Campaign behavior
local function handleProcessingError(errorContext, operation, errorDetails, fallbackValue)
if errorContext then
local contextName = getContextName(errorContext)
local message = getErrorMessage(contextName, operation)
-- Preserve existing detailed error format for campaigns
if contextName == 'campaignBanner' then
ErrorHandling.addStatus(errorContext, contextName, message, errorDetails)
else
-- Simplified error reporting for new contexts
ErrorHandling.addStatus(errorContext, contextName, message, nil)
end
end
return fallbackValue
end
-- Constants as upvalues for performance
local WIKI_LINK_PATTERNS = {
-- Pattern 1: [[Page Name]] -> HTML page links
{
pattern = '%[%[([^#|%]]+)%]%]',
processor = function(pageName, errorContext)
-- Step 1: Generate URL
local spacesReplaced = (pageName:gsub(' ', '_'))
local success1, pageUrl = pcall(function()
return tostring(mw.uri.fullUrl(spacesReplaced))
end)
if not success1 then
return handleProcessingError(errorContext, 'urlFailed',
'Page: ' .. pageName .. ', Error: ' .. tostring(pageUrl),
'[[' .. pageName .. ']]')
end
-- Step 2: Encode text
local pageNameStr = type(pageName) == "string" and pageName or tostring(pageName)
local success2, encodedName = pcall(mw.text.encode, pageNameStr)
if not success2 then
return handleProcessingError(errorContext, 'encodeFailed',
'Page: ' .. pageName .. ', Error: ' .. tostring(encodedName),
'[[' .. pageName .. ']]')
end
-- Step 3: Format HTML
local success3, result = pcall(string.format, '<a href="%s">%s</a>', pageUrl, encodedName)
if not success3 then
return handleProcessingError(errorContext, 'formatFailed',
'Page: ' .. pageName .. ', Error: ' .. tostring(result),
'[[' .. pageName .. ']]')
end
return result
end
},
-- Pattern 2: [[Page|text]] -> HTML page links with custom text
{
pattern = '%[%[([^#|%]]+)|([^%]]+)%]%]',
processor = function(pageName, text, errorContext)
-- Step 1: Generate URL
local success1, pageUrl = pcall(function()
return tostring(mw.uri.fullUrl((pageName:gsub(' ', '_'))))
end)
if not success1 then
return handleProcessingError(errorContext, 'urlFailedPattern2',
'Error: ' .. tostring(pageUrl),
'[[' .. pageName .. '|' .. text .. ']]')
end
-- Step 2: Encode text
local textStr = type(text) == "string" and text or tostring(text)
local success2, encodedText = pcall(mw.text.encode, textStr)
if not success2 then
return handleProcessingError(errorContext, 'encodeFailedPattern2',
'Error: ' .. tostring(encodedText),
'[[' .. pageName .. '|' .. text .. ']]')
end
-- Step 3: Format HTML
local success3, result = pcall(string.format, '<a href="%s">%s</a>', pageUrl, encodedText)
if not success3 then
return handleProcessingError(errorContext, 'formatFailedPattern2',
'Error: ' .. tostring(result),
'[[' .. pageName .. '|' .. text .. ']]')
end
return result
end
},
-- Pattern 3: [[#anchor|text]] -> HTML anchor links
{
pattern = '%[%[#([^|%]]+)|([^%]]+)%]%]',
processor = function(anchor, text, errorContext)
local success1, encodedAnchor = pcall(function()
return mw.uri.anchorEncode(anchor)
end)
if not success1 then
if errorContext then
ErrorHandling.addStatus(errorContext, 'campaignBanner', 'Pattern 3 mw.uri.anchorEncode failed', 'Error: ' .. tostring(encodedAnchor))
end
return '[[#' .. anchor .. '|' .. text .. ']]'
end
local success2, encodedText = pcall(function()
-- Ensure text is a string before encoding
local textStr = type(text) == "string" and text or tostring(text)
return mw.text.encode(textStr)
end)
if not success2 then
if errorContext then
ErrorHandling.addStatus(errorContext, 'campaignBanner', 'Pattern 3 mw.text.encode failed', 'Error: ' .. tostring(encodedText))
end
return '[[#' .. anchor .. '|' .. text .. ']]'
end
local success3, result = pcall(function()
return string.format('<a href="#%s">%s</a>', encodedAnchor, encodedText)
end)
if not success3 then
if errorContext then
ErrorHandling.addStatus(errorContext, 'campaignBanner', 'Pattern 3 string.format failed', 'Error: ' .. tostring(result))
end
return '[[#' .. anchor .. '|' .. text .. ']]'
end
return result
end
}
}
-- Normalizes content string by cleaning up whitespace
function p.normalizeContentString(content)
if not content or content == "" then
return content
end
-- Apply string normalization exactly like the original T-Campaign code
return content:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
end
-- Replaces placeholder patterns ($VARIABLE$) with actual values
function p.replacePlaceholders(content, placeholderMap)
if not content or not placeholderMap then
return content
end
local result = content
-- Apply placeholder replacement exactly like the original T-Campaign code
for key, value in pairs(placeholderMap) do
if value and value ~= "" then
result = result:gsub("%$" .. key .. "%$", value)
end
end
-- Clean up any remaining unfilled placeholders (TemplateStarter's removeEmptyPlaceholders logic)
result = result:gsub("%$[A-Z_]+%$", "")
result = result:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
return result
end
-- Processes wiki links in content and converts them to HTML
function p.processWikiLinksToHTML(content, errorContext)
if not content or content == "" then
return content
end
-- UNIFIED PIPELINE: Process ALL wiki links with custom patterns (no frame:preprocess)
local originalContent = content
local result = content
-- Process each wiki link pattern in sequence exactly like the original T-Campaign code
for _, patternInfo in ipairs(WIKI_LINK_PATTERNS) do
result = result:gsub(patternInfo.pattern, function(...)
return patternInfo.processor(..., errorContext)
end)
end
return result
end
-- Main entry point: Processes JSON content with wikitext formatting for frontend display
-- @param content The content string to process
-- @param placeholders Optional table of placeholder values for $VARIABLE$ replacement
-- @param errorContext Optional error context for error reporting
-- @return Processed content ready for frontend display
function p.processContentForFrontend(content, placeholders, errorContext)
if not content or content == "" then
return content
end
-- Step 1: Normalize content string
local processedContent = p.normalizeContentString(content)
-- Step 2: Replace placeholders if provided
if placeholders then
processedContent = p.replacePlaceholders(processedContent, placeholders)
end
-- Step 3: Process wiki links to HTML
processedContent = p.processWikiLinksToHTML(processedContent, errorContext)
return processedContent
end
return p