Module:TemplateHelpers: Difference between revisions
// via Wikitext Extension for VSCode Tag: Reverted |
// via Wikitext Extension for VSCode |
||
| (9 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
-- | --[[ | ||
* Name: TemplateHelpers | |||
* Author: Mark W. Datysgeld | |||
* Description: Common helper functions for template modules promoting code reuse and consistency across string processing, field handling, normalization, and block rendering | |||
* Notes: String processing functions for manipulating strings and template arguments; field processing functions for handling template fields and values; normalization wrappers for standardizing data formats; block generation helpers for rendering template blocks; category and semantic utilities (DEPRECATED wrappers for SemanticCategoryHelpers); configuration standardization for creating standard config structures; includes caching mechanism and multi-value string processing | |||
]] | |||
local p = {} | local p = {} | ||
-- Dependencies | |||
local linkParser = require('Module:LinkParser') | |||
local CountryData = require('Module:CountryData') | |||
local dateNormalization = require('Module:NormalizationDate') | |||
local CanonicalForms = require('Module:CanonicalForms') | |||
local NormalizationText = require('Module:NormalizationText') | |||
local ListGeneration = require('Module:ListGeneration') | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 74: | Line 77: | ||
p.FIELD_FORMAT_WITH_TOOLTIP = FIELD_FORMAT_WITH_TOOLTIP | p.FIELD_FORMAT_WITH_TOOLTIP = FIELD_FORMAT_WITH_TOOLTIP | ||
-- | -- Registry for declarative list post-processors | ||
local | local listPostProcessors = { | ||
local | language = function(itemContent) | ||
local | local NormalizationLanguage = require('Module:NormalizationLanguage') | ||
local | local langName = NormalizationLanguage.normalize(itemContent) | ||
local nativeName = NormalizationLanguage.getNativeForm(langName) | |||
local | if nativeName and langName ~= "English" then | ||
return string.format('%s<br/><span style="display:inline-block; width:0.1em; visibility:hidden;">*</span><span style="font-size:75%%;">%s</span>', langName, nativeName) | |||
else | |||
return langName | |||
end | |||
end, | |||
website = function(itemContent) | |||
local linkUrl = itemContent | |||
if not linkUrl:match("^%a+://") then | |||
linkUrl = "https://" .. linkUrl | |||
end | |||
return string.format("[%s %s]", linkUrl, require('Module:LinkParser').strip(itemContent)) | |||
end, | |||
autoWikiLink = function(itemContent) | |||
-- Trim whitespace and check for existing wiki links | |||
local trimmedContent = p.trim(itemContent) | |||
if linkParser.processWikiLink(trimmedContent, "check") then | |||
-- Extract page name and display text | |||
local pageName, displayText = trimmedContent:match("^%[%[([^|]+)|?(.*)%]%]$") | |||
-- Normalize by trimming whitespace | |||
pageName = p.trim(pageName or "") | |||
displayText = p.trim(displayText or "") | |||
-- Reconstruct link, omitting display text if it's same as page name | |||
if displayText == "" or displayText == pageName then | |||
return string.format("[[%s]]", pageName) | |||
else | |||
return string.format("[[%s|%s]]", pageName, displayText) | |||
end | |||
else | |||
-- Not a wiki link, so just wrap it | |||
return string.format("[[%s]]", trimmedContent) | |||
end | |||
end | |||
} | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 430: | Line 468: | ||
-- Handle declarative lists first | -- Handle declarative lists first | ||
if field.list then | if field.list then | ||
local items = NormalizationText.splitMultiValueString(value) | -- Use a safe, semicolon-only pattern to avoid breaking up valid names. | ||
local semicolonOnlyPattern = {{pattern = ";%s*", replacement = ";"}} | |||
local items = NormalizationText.splitMultiValueString(value, semicolonOnlyPattern) | |||
if #items > 0 then | if #items > 0 then | ||
local options = {} | local options = {} | ||
| Line 441: | Line 481: | ||
end | end | ||
-- Chain post-processors declaratively | |||
local processorsToApply = {} | |||
if field.autoWikiLink then | if field.autoWikiLink then | ||
local originalHook = options.itemHook | table.insert(processorsToApply, "autoWikiLink") | ||
end | |||
if options.postProcess then | |||
table.insert(processorsToApply, options.postProcess) | |||
end | |||
for _, processorName in ipairs(processorsToApply) do | |||
local | local processorFunc = listPostProcessors[processorName] | ||
if processorFunc then | |||
local originalHook = options.itemHook | |||
options.itemHook = function(item) | |||
if type(originalHook) == 'function' then | |||
item = originalHook(item) | |||
end | |||
local itemContent = type(item) == 'table' and item.content or item | |||
local processedContent = processorFunc(itemContent) | |||
if type(item) == 'table' then | if type(item) == 'table' then | ||
item.content = | item.content = processedContent | ||
return item | return item | ||
else | else | ||
return | return processedContent | ||
end | end | ||
end | end | ||
end | end | ||
end | end | ||