Module:CRTModel: Difference between revisions

Add Parts section to CRT model infobox (queries parts linked via Has related CRT model) (via update-page on MediaWiki MCP Server)
Change "Add accessory" button to link to Create_an_accessory with crt_models parameter (via update-page on MediaWiki MCP Server)
 
(15 intermediate revisions by the same user not shown)
Line 228: Line 228:
local model_code = trim(args.model_code)
local model_code = trim(args.model_code)
local variants = trim(args.variants)
local variants = trim(args.variants)
local market = trim(args.market)
local series = trim(args.series)
local series = trim(args.series)
local image_main = trim(args.image_main)
local image_main = trim(args.image_main)
Line 296: Line 297:
'infobox-title'
'infobox-title'
)
)
-- Type badge (breadcrumb) — plainlinks hides external icon, $wgNoFollowDomainExceptions handles nofollow
local badgeWikitext = '[[CRT Search|CRT]]'
if crt_type then
local typeUrl = mw.title.new('CRT Search'):fullUrl({crt_type = crt_type})
badgeWikitext = badgeWikitext .. ' › <span class="plainlinks">[' .. typeUrl .. ' ' .. crt_type .. ']</span>'
end
addFullRow(container, badgeWikitext, '', false, 'infobox-type-badge')


if image_main then
if image_main then
Line 341: Line 350:
if variants then
if variants then
addRow(container, 'Variants', variants, false)
addRow(container, 'Variants', variants, false)
end
-- Market row
if market then
addRow(container, 'Market', market, false)
end
end


Line 559: Line 573:
if range.min and range.max then
if range.min and range.max then
if range.min == range.max then
if range.min == range.max then
-- Single voltage (e.g., "120V")
rangeStr = range.min .. 'V'
rangeStr = range.min .. 'V'
else
else
-- Range (e.g., "100–120V")
rangeStr = range.min .. '–' .. range.max .. 'V'
rangeStr = range.min .. '–' .. range.max .. 'V'
end
end
Line 576: Line 588:
if #rangeStrings > 0 then
if #rangeStrings > 0 then
-- Join multiple ranges with " / " (e.g., "100–120V / 220–240V")
addRow(container, 'Voltage', table.concat(rangeStrings, ' / '), false)
addRow(container, 'Voltage', table.concat(rangeStrings, ' / '), false)
end
end
Line 604: Line 615:
addSectionRow(container, 'TV Systems')
addSectionRow(container, 'TV Systems')
-- AV system row (baseband video color support)
if av_system then
if av_system then
-- Link each system to its wiki page
local systems = {}
local systems = {}
for system in av_system:gmatch('[^,]+') do
for system in av_system:gmatch('[^,]+') do
Line 619: Line 628:
end
end
-- Tuner system row (RF broadcast standards)
if tuner_system then
if tuner_system then
-- Link each system to its wiki page
local systems = {}
local systems = {}
for system in tuner_system:gmatch('[^,]+') do
for system in tuner_system:gmatch('[^,]+') do
Line 635: Line 642:
end
end


-- Scan Range section: show if we have any scan range specs
-- Scan Range section
if h_scan_min or h_scan_max or v_scan_min or v_scan_max then
if h_scan_min or h_scan_max or v_scan_min or v_scan_max then
addSectionRow(container, 'Scan Range')
addSectionRow(container, 'Scan Range')
-- Horizontal scan row
if h_scan_min or h_scan_max then
if h_scan_min or h_scan_max then
local hDisplay
local hDisplay
if h_scan_min and h_scan_max then
if h_scan_min and h_scan_max then
if h_scan_min == h_scan_max then
if h_scan_min == h_scan_max then
-- Single frequency (e.g., "15.7 kHz")
hDisplay = h_scan_min .. ' kHz'
hDisplay = h_scan_min .. ' kHz'
else
else
-- Range (e.g., "15–100 kHz")
hDisplay = h_scan_min .. '–' .. h_scan_max .. ' kHz'
hDisplay = h_scan_min .. '–' .. h_scan_max .. ' kHz'
end
end
Line 658: Line 662:
end
end
-- Vertical scan row
if v_scan_min or v_scan_max then
if v_scan_min or v_scan_max then
local vDisplay
local vDisplay
if v_scan_min and v_scan_max then
if v_scan_min and v_scan_max then
if v_scan_min == v_scan_max then
if v_scan_min == v_scan_max then
-- Single frequency (e.g., "60 Hz")
vDisplay = v_scan_min .. ' Hz'
vDisplay = v_scan_min .. ' Hz'
else
else
-- Range (e.g., "50–160 Hz")
vDisplay = v_scan_min .. '–' .. v_scan_max .. ' Hz'
vDisplay = v_scan_min .. '–' .. v_scan_max .. ' Hz'
end
end
Line 679: Line 680:


-- Inputs, Outputs, and Control Ports sections
-- Inputs, Outputs, and Control Ports sections
-- Dynamically discover locations from semantic data instead of hardcoding
-- Helper closure to render an I/O section with dynamically discovered location-based rows
local function renderIOSection(sectionTitle, ioType)
local function renderIOSection(sectionTitle, ioType)
local locations = discoverLocations(frame, fullPageName, ioType)
local locations = discoverLocations(frame, fullPageName, ioType)
Line 713: Line 711:
renderIOSection('Control Ports', 'control')
renderIOSection('Control Ports', 'control')


-- Accessories section: Query for non-remote accessories linked via Has related CRT model
-- Accessories section
addSectionRow(container, 'Accessories')
 
local addAccessoryUrl = mw.uri.fullUrl(
"Create an accessory",
{
crt_models = pageName
}
)
 
local accessoriesCountWikitext =
local accessoriesCountWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 723: Line 730:
local accessoryCount = frame:preprocess(accessoriesCountWikitext)
local accessoryCount = frame:preprocess(accessoriesCountWikitext)
local hasAccessories = accessoryCount and tonumber(trim(accessoryCount)) and tonumber(trim(accessoryCount)) > 0
local hasAccessories = accessoryCount and tonumber(trim(accessoryCount)) and tonumber(trim(accessoryCount)) > 0
 
local accDiv = container:tag('div')
css(accDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
 
if hasAccessories then
if hasAccessories then
addSectionRow(container, 'Accessories')
-- Query accessories and display grouped by type
local accessoriesQueryWikitext =
local accessoriesQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 735: Line 742:
' |?Has accessory type=type\n' ..
' |?Has accessory type=type\n' ..
' |?Has model code=model\n' ..
' |?Has model code=model\n' ..
' |?Has description=desc\n' ..
' |format=broadtable\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |headers=hide\n' ..
Line 741: Line 747:
'}}'
'}}'
local accessoriesResult = frame:preprocess(accessoriesQueryWikitext)
local accessoriesResult = frame:preprocess(accessoriesQueryWikitext)
 
-- Parse accessories from broadtable result and group by type
local accessoriesByType = {}
local accessoriesByType = {}
local typeOrder = {}
local typeOrder = {}
 
if accessoriesResult then
if accessoriesResult then
for rowContent in accessoriesResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in accessoriesResult:gmatch('<tr[^>]*>(.-)</tr>') do
Line 753: Line 758:
table.insert(cells, trim(cleanContent))
table.insert(cells, trim(cleanContent))
end
end
 
-- cells[1] = page name, cells[2] = type, cells[3] = model code, cells[4] = description
if #cells >= 2 then
if #cells >= 2 then
local accPageName = cells[1]
local accPageName = cells[1]
local accType = cells[2] or 'Accessory'
local accType = cells[2] or 'Accessory'
local accDesc = cells[4]
 
if accPageName then
if accPageName then
-- Track type order for consistent display
if not accessoriesByType[accType] then
if not accessoriesByType[accType] then
accessoriesByType[accType] = {}
accessoriesByType[accType] = {}
table.insert(typeOrder, accType)
table.insert(typeOrder, accType)
end
end
 
table.insert(accessoriesByType[accType], {
table.insert(accessoriesByType[accType], {
page = accPageName,
page = accPageName
desc = accDesc
})
})
end
end
Line 775: Line 776:
end
end
end
end
 
-- Display as label/value rows grouped by type (like Archival Links)
local accGrid = accDiv:tag('div')
css(accGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
 
for _, accType in ipairs(typeOrder) do
for _, accType in ipairs(typeOrder) do
local accs = accessoriesByType[accType]
local accs = accessoriesByType[accType]
Line 782: Line 785:
local accLinks = {}
local accLinks = {}
for _, acc in ipairs(accs) do
for _, acc in ipairs(accs) do
local displayText = getDisplayTextWithoutBrand(acc.page, brand)
table.insert(accLinks, '[[' .. acc.page .. ']]')
local linkText = displayText
if acc.desc and acc.desc ~= '' then
linkText = displayText .. ' – ' .. acc.desc
end
table.insert(accLinks, '[[' .. acc.page .. '|' .. linkText .. ']]')
end
end
addRow(container, accType, table.concat(accLinks, '<br>'), true)
 
local labelDiv = accGrid:tag('div')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext(accType)
 
local valueDiv = accGrid:tag('div')
valueDiv:addClass('infobox-value')
css(valueDiv, 'padding:0.2em 0.4em;')
valueDiv:wikitext(table.concat(accLinks, '<br>'))
end
end
end
end
local addAccDiv = mw.html.create('div')
addAccDiv:css('margin-top', '0.5em'):css('text-align', 'center')
addAccDiv:wikitext('[' .. tostring(addAccessoryUrl) .. ' <span class="infobox-button infobox-button-secondary">Add accessory</span>]')
accDiv:node(addAccDiv)
else
local addAccDiv = mw.html.create('div')
addAccDiv:css('text-align', 'center')
addAccDiv:wikitext('[' .. tostring(addAccessoryUrl) .. ' <span class="infobox-button infobox-button-secondary">Add accessory</span>]')
accDiv:node(addAccDiv)
end
end


-- Parts section: Query for parts linked via Has related CRT model
-- Parts section
addSectionRow(container, 'Parts')
local addPartUrl = mw.uri.fullUrl(
"Create a part",
{
crt_models = pageName
}
)
local partsCountWikitext =
local partsCountWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 803: Line 829:
local partsCount = frame:preprocess(partsCountWikitext)
local partsCount = frame:preprocess(partsCountWikitext)
local hasParts = partsCount and tonumber(trim(partsCount)) and tonumber(trim(partsCount)) > 0
local hasParts = partsCount and tonumber(trim(partsCount)) and tonumber(trim(partsCount)) > 0
local partsDiv = container:tag('div')
css(partsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
if hasParts then
if hasParts then
addSectionRow(container, 'Parts')
-- Query parts and display grouped by type/subtype
local partsQueryWikitext =
local partsQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 815: Line 841:
' |?Has part subtype=subtype\n' ..
' |?Has part subtype=subtype\n' ..
' |?Has model code=model\n' ..
' |?Has model code=model\n' ..
' |?Has description=desc\n' ..
' |format=broadtable\n' ..
' |format=broadtable\n' ..
' |headers=hide\n' ..
' |headers=hide\n' ..
Line 822: Line 847:
local partsResult = frame:preprocess(partsQueryWikitext)
local partsResult = frame:preprocess(partsQueryWikitext)
-- Parse parts from broadtable result and group by type
local partsByType = {}
local partsByType = {}
local partTypeOrder = {}
local partTypeOrder = {}
Line 834: Line 858:
end
end
-- cells[1] = page name, cells[2] = type, cells[3] = subtype, cells[4] = model code, cells[5] = description
if #cells >= 2 then
if #cells >= 2 then
local partPageName = cells[1]
local partPageName = cells[1]
local partType = cells[2] or 'Part'
local partType = cells[2] or 'Part'
local partSubtype = cells[3]
local partSubtype = cells[3]
local partDesc = cells[5]
-- Use subtype + type as the grouping key if subtype exists (e.g., "Jungle IC")
local groupKey = partType
local groupKey = partType
if partSubtype and partSubtype ~= '' then
if partSubtype and partSubtype ~= '' then
groupKey = partSubtype .. ' ' .. partType:lower()
groupKey = partSubtype .. ' ' .. partType
end
end
if partPageName then
if partPageName then
-- Track type order for consistent display
if not partsByType[groupKey] then
if not partsByType[groupKey] then
partsByType[groupKey] = {}
partsByType[groupKey] = {}
Line 855: Line 875:
table.insert(partsByType[groupKey], {
table.insert(partsByType[groupKey], {
page = partPageName,
page = partPageName
desc = partDesc
})
})
end
end
Line 863: Line 882:
end
end
-- Display as label/value rows grouped by type
local partsGrid = partsDiv:tag('div')
css(partsGrid, 'display:grid; grid-template-columns:auto 1fr; gap:3px;')
for _, partType in ipairs(partTypeOrder) do
for _, partType in ipairs(partTypeOrder) do
local parts = partsByType[partType]
local parts = partsByType[partType]
Line 869: Line 890:
local partLinks = {}
local partLinks = {}
for _, part in ipairs(parts) do
for _, part in ipairs(parts) do
local displayText = getDisplayTextWithoutBrand(part.page, brand)
table.insert(partLinks, '[[' .. part.page .. ']]')
local linkText = displayText
if part.desc and part.desc ~= '' then
linkText = displayText .. ' – ' .. part.desc
end
table.insert(partLinks, '[[' .. part.page .. '|' .. linkText .. ']]')
end
end
addRow(container, partType, table.concat(partLinks, '<br>'), true)
local labelDiv = partsGrid:tag('div')
labelDiv:addClass('infobox-label')
css(labelDiv, 'padding:0.2em 0.4em; font-weight:bold; text-align:left;')
labelDiv:wikitext(partType)
local valueDiv = partsGrid:tag('div')
valueDiv:addClass('infobox-value')
css(valueDiv, 'padding:0.2em 0.4em;')
valueDiv:wikitext(table.concat(partLinks, '<br>'))
end
end
end
end
local addPartDiv = mw.html.create('div')
addPartDiv:css('margin-top', '0.5em'):css('text-align', 'center')
addPartDiv:wikitext('[' .. tostring(addPartUrl) .. ' <span class="infobox-button infobox-button-secondary">Add part</span>]')
partsDiv:node(addPartDiv)
else
local addPartDiv = mw.html.create('div')
addPartDiv:css('text-align', 'center')
addPartDiv:wikitext('[' .. tostring(addPartUrl) .. ' <span class="infobox-button infobox-button-secondary">Add part</span>]')
partsDiv:node(addPartDiv)
end
end


-- Mods section: Query for mod subobjects and display
-- Mods section
local modsQueryWikitext =
local modsQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 896: Line 931:
local modsResult = frame:preprocess(modsQueryWikitext)
local modsResult = frame:preprocess(modsQueryWikitext)
-- Parse mods from broadtable result
local mods = {}
local mods = {}
Line 937: Line 971:
end
end
-- Display mods section if there are any
if #mods > 0 then
if #mods > 0 then
addSectionRow(container, 'Mods')
addSectionRow(container, 'Mods')
Line 950: Line 983:
local li = ul:tag('li')
local li = ul:tag('li')
-- Determine display text: use description if available, otherwise type
local displayText = mod.description or mod.type
local displayText = mod.description or mod.type
-- Check if mod is not feasible
local isFeasible = mod.feasible ~= 'No'
local isFeasible = mod.feasible ~= 'No'
if isFeasible then
if isFeasible then
-- Normal link for feasible mods using wikitext external link
li:wikitext('[' .. mod.url .. ' ' .. displayText .. ']')
li:wikitext('[' .. mod.url .. ' ' .. displayText .. ']')
else
else
-- Red styling with X for impossible mods
local wrapper = li:tag('span')
local wrapper = li:tag('span')
wrapper:addClass('mod-not-feasible')
wrapper:addClass('mod-not-feasible')
Line 974: Line 1,002:
addSectionRow(container, 'Documents')
addSectionRow(container, 'Documents')
-- Build the upload link with pseudorandom unique identifier
local timestamp = os.time()
local timestamp = os.time()
math.randomseed(timestamp + pageId) -- Seed with timestamp + page ID for better randomness
math.randomseed(timestamp + pageId)
local random = math.random(1000, 9999)
local random = math.random(1000, 9999)
local target = "Document:" .. timestamp .. "-" .. random
local target = "Document:" .. timestamp .. "-" .. random
Line 988: Line 1,015:
)
)
-- Query for document count
local documentsCountWikitext =
local documentsCountWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 998: Line 1,024:
local hasDocuments = documentCount and tonumber(trim(documentCount)) and tonumber(trim(documentCount)) > 0
local hasDocuments = documentCount and tonumber(trim(documentCount)) and tonumber(trim(documentCount)) > 0
-- Create the content div
local docsDiv = container:tag('div')
local docsDiv = container:tag('div')
css(docsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
css(docsDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em;')
if hasDocuments then
if hasDocuments then
-- Use #ask to get documents
local docsQueryWikitext =
local docsQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 1,018: Line 1,042:
local docsResult = frame:preprocess(docsQueryWikitext)
local docsResult = frame:preprocess(docsQueryWikitext)
-- Create UL element
local ul = mw.html.create('ul')
local ul = mw.html.create('ul')
ul:css('margin', '0'):css('padding-left', '1.5em')
ul:css('margin', '0'):css('padding-left', '1.5em')
-- Parse the HTML table - extract data from <td> tags
if docsResult then
if docsResult then
-- Match each table row
for rowContent in docsResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in docsResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
-- Extract content from each <td>
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
-- Strip any remaining HTML tags and get just the text
local cleanContent = cellContent:gsub('<[^>]+>', '')
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, cleanContent)
table.insert(cells, cleanContent)
end
end
-- cells[1] = page name, cells[2] = type, cells[3] = URL, cells[4] = file, cells[5] = title
if #cells >= 2 then
if #cells >= 2 then
local docType = trim(cells[2])
local docType = trim(cells[2])
Line 1,041: Line 1,059:
local docTitle = trim(cells[5])
local docTitle = trim(cells[5])
-- Determine what to link to (URL or file)
local linkTarget = nil
local linkTarget = nil
if docUrl then
if docUrl then
linkTarget = docUrl
linkTarget = docUrl
elseif docFile then
elseif docFile then
-- Extract filename from "File:..." format if present
local filename = docFile:match('File:(.+)') or docFile
local filename = docFile:match('File:(.+)') or docFile
linkTarget = tostring(mw.uri.fullUrl('File:' .. filename))
linkTarget = tostring(mw.uri.fullUrl('File:' .. filename))
end
end


-- Always link to the wiki page
local docPageName = trim(cells[1])
local docPageName = trim(cells[1])
if docPageName then
if docPageName then
-- Determine display text priority: custom title > type > default
local displayText = 'Document'
local displayText = 'Document'
if docTitle then
if docTitle then
Line 1,063: Line 1,077:
end
end
-- Create list item with link to wiki page
local li = ul:tag('li')
local li = ul:tag('li')
li:wikitext('[[' .. docPageName .. '|' .. displayText .. ']]')
li:wikitext('[[' .. docPageName .. '|' .. displayText .. ']]')
Line 1,073: Line 1,086:
docsDiv:node(ul)
docsDiv:node(ul)
-- Add upload link as a button
local uploadDiv = mw.html.create('div')
local uploadDiv = mw.html.create('div')
uploadDiv:css('margin-top', '0.5em'):css('text-align', 'center')
uploadDiv:css('margin-top', '0.5em'):css('text-align', 'center')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add a document</span>]')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
docsDiv:node(uploadDiv)
docsDiv:node(uploadDiv)
else
else
-- Just show the upload link as a button
local uploadDiv = mw.html.create('div')
local uploadDiv = mw.html.create('div')
uploadDiv:css('text-align', 'center')
uploadDiv:css('text-align', 'center')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add a document</span>]')
uploadDiv:wikitext('[' .. tostring(uploadUrl) .. ' <span class="infobox-button infobox-button-secondary">Add document</span>]')
docsDiv:node(uploadDiv)
docsDiv:node(uploadDiv)
end
end


-- Links section: Query for link subobjects and display by type
-- Links section
local linksQueryWikitext =
local linksQueryWikitext =
'{{#ask:\n' ..
'{{#ask:\n' ..
Line 1,101: Line 1,112:
local linksResult = frame:preprocess(linksQueryWikitext)
local linksResult = frame:preprocess(linksQueryWikitext)
-- Parse links and organize by type
local linksByType = {
local linksByType = {
Manufacturer = {},
Manufacturer = {},
Line 1,110: Line 1,120:
if linksResult then
if linksResult then
-- Match each table row
for rowContent in linksResult:gmatch('<tr[^>]*>(.-)</tr>') do
for rowContent in linksResult:gmatch('<tr[^>]*>(.-)</tr>') do
local cells = {}
local cells = {}
-- Extract content from each <td>
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
for cellContent in rowContent:gmatch('<td[^>]*>(.-)</td>') do
-- Strip any remaining HTML tags and get just the text
local cleanContent = cellContent:gsub('<[^>]+>', '')
local cleanContent = cellContent:gsub('<[^>]+>', '')
table.insert(cells, trim(cleanContent))
table.insert(cells, trim(cleanContent))
end
end
-- cells[1] = page/subobject, cells[2] = type, cells[3] = source, cells[4] = URL
if #cells >= 4 then
if #cells >= 4 then
local linkType = cells[2]
local linkType = cells[2]
Line 1,136: Line 1,142:
end
end
-- Display links section if there are any links
if hasLinks then
if hasLinks then
addSectionRow(container, 'Archival Links')
addSectionRow(container, 'Archival Links')
-- Add links in order: Database, Manufacturer, Retailer
local linkTypeOrder = {'Database', 'Manufacturer', 'Retailer'}
local linkTypeOrder = {'Database', 'Manufacturer', 'Retailer'}
for _, linkType in ipairs(linkTypeOrder) do
for _, linkType in ipairs(linkTypeOrder) do
if #linksByType[linkType] > 0 then
if #linksByType[linkType] > 0 then
-- If multiple links of the same type, combine them in one row
local linksHtml = {}
local linksHtml = {}
for _, link in ipairs(linksByType[linkType]) do
for _, link in ipairs(linksByType[linkType]) do
Line 1,157: Line 1,160:
addSectionRow(container, 'Contribute')
addSectionRow(container, 'Contribute')
-- Build the edit link URL
local editUrl = mw.uri.fullUrl(
local editUrl = mw.uri.fullUrl(
"Special:FormStart",
"Special:FormStart",
Line 1,166: Line 1,168:
)
)
-- Create the edit button div
local editDiv = container:tag('div')
local editDiv = container:tag('div')
css(editDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em; text-align:center;')
css(editDiv, 'grid-column: 1 / -1; padding:0.2em 0.4em; text-align:center;')
-- Add edit button with primary action styling (using class for night mode compatibility)
editDiv:wikitext('[' .. tostring(editUrl) .. ' <span class="infobox-button infobox-button-primary">Edit this data</span>]')
editDiv:wikitext('[' .. tostring(editUrl) .. ' <span class="infobox-button infobox-button-primary">Edit this data</span>]')


-- Return templatestyles tag + container HTML
return styleTag .. tostring(container)
return styleTag .. tostring(container)
end
end


return p
return p
MediaWiki Appliance - Powered by TurnKey Linux