This template implements {{popular list}}, as {{#invoke:Popular list|top7}}.
This template implements {{popular list}}, as {{#invoke:Popular list|top7}}.
|1= (Required)Wikipedia:WikiProject Comics/Popular pages). The page must contain a wikitable with "Rank", "Page", and "Views" headers. Column order does not matter as long as headers are present.|2= (Optional)7.'
local p = {}
---------------------------------------------
-- Helper function to parse a row from a
-- wikitext table.
---------------------------------------------
local function parseRow(cells, headerMap)
-- We need rank, page title, and views
if not (headerMap.rank and headerMap.page and headerMap.views) then
return nil
end
local entry = {}
-- rank
entry.rank = tonumber(cells[headerMap.rank])
-- page title
local pageCell = cells[headerMap.page] or ""
entry.page = pageCell:match("%[%[:?([^|%]]+)")
-- views
local viewsCell = cells[headerMap.views] or ""
local viewsNum = viewsCell:match("{{FORMATNUM:(%d+)}}") or viewsCell:match("(%d+)")
entry.views = tonumber(viewsNum)
-- toolforge URL
if entry.page then
entry.url = "https://pageviews.toolforge.org/?project=en.wikipedia.org&pages=" .. entry.page:gsub(" ", "_")
end
-- assessment (optional)
if headerMap.assessment and cells[headerMap.assessment] then
local cell = cells[headerMap.assessment]
entry.assessment = cell:match("Category:([^%-]+)%-Class") or cell:match("{{([^}%-]+)%-Class}}")
end
-- importance (optional)
if headerMap.importance and cells[headerMap.importance] then
local cell = cells[headerMap.importance]
entry.importance = cell:match("Category:([^%-]+)%-importance") or cell:match("{{([^}%-]+)%-importance}}")
end
-- ensure we have the required data
-- (we can render without assessment or importance)
return (entry.rank and entry.page and entry.views) and entry or nil
end
---------------------------------------------
-- Main function top7 will create a list of 7
-- or specified number of list items.
---------------------------------------------
function p.top7(frame)
local pageName = frame.args[1] or ""
local limit = tonumber(frame.args[2]) or 7
if pageName == "" then
return "ERROR: Missing page name parameter ([[Template:Popular list/doc#Missing page name parameter|help]])"
end
local title = mw.title.new(pageName)
if not title then
return "ERROR: Invalid page name '" .. pageName .. "' ([[Template:Popular list/doc#Invalid page name|help]])"
end
local pageContent = title and title:getContent()
if not pageContent then
return "ERROR: Page does not exist or cannot be read ([[Template:Popular list/doc#Page does not exist|help]])"
end
-- NORMALIZATION: Handle double-pipes and double-exclamations
pageContent = pageContent:gsub("%s*||%s*", "\n|"):gsub("%s*!!%s*", "\n!")
local entries = {}
local headerMap = {}
local currentRow = {}
local inTable = false
-- Line-by-line processing
for line in (pageContent .. "\n"):gmatch("(.-)\n") do
line = mw.text.trim(line)
if line:match("^{|") then
inTable = true
elseif line:match("^|}") then
-- Process the final row before closing
if #currentRow > 0 and inTable then
local entry = parseRow(currentRow, headerMap)
if entry and entry.rank <= limit then table.insert(entries, entry) end
end
break
elseif inTable and line:match("^[|!]%-") then
-- A row is finished. Determine if it was a Header row or Data row.
if #currentRow > 0 then
local isHeaderRow = false
for _, val in ipairs(currentRow) do
if val:find("Rank") or val:find("Page") then isHeaderRow = true break end
end
if isHeaderRow then
for i, content in ipairs(currentRow) do
local lowContent = content:lower()
if lowContent:find("rank") then headerMap.rank = i
elseif lowContent:find("page") or lowContent:find("article") then headerMap.page = i
elseif lowContent:find("class") or lowContent:find("assessment") then headerMap.assessment = i
elseif lowContent:find("importance") then headerMap.importance = i
-- Precision Views check (excludes "daily", "day", etc.)
elseif lowContent:find("views") and not lowContent:find("da") then
if content == "Views" or not headerMap.views then
headerMap.views = i
end
end
end
else
-- It's a data row, parse it using the map we built
local entry = parseRow(currentRow, headerMap)
if entry and entry.rank <= limit then
table.insert(entries, entry)
end
end
end
currentRow = {}
elseif inTable and (line:match("^|") or line:match("^!")) then
-- Capture cell content, removing the leading | or !
local cellData = line:match("^[|!]+%s*(.*)$")
if cellData then table.insert(currentRow, cellData) end
end
end
-- Validate that we actually found the table structure
if not (headerMap.rank and headerMap.page and headerMap.views) then
return "ERROR: No wikitable found on page ([[Template:Popular list/doc#No wikitable found on page|help]])"
end
if #entries == 0 then
return "ERROR: No entries found in table ([[Template:Popular list/doc#No entries found in table|help]])"
end
-- Sort by rank (1, 2, 3...)
table.sort(entries, function(a, b) return a.rank < b.rank end)
-- BUILD OUTPUT (Your "Pile-on" Logic)
local list = mw.html.create('ol'):addClass('popular-list')
for _, entry in ipairs(entries) do
local formattedViews = mw.language.getContentLanguage():formatNum(entry.views)
local annotatedLink = frame:preprocess("{{Annotated link|" .. entry.page .. "}}")
-- Start string: (VIEWS
local metaStr = "(" .. string.format("[%s %s views]", entry.url, formattedViews)
-- Add Assessment if it exists
if entry.assessment and entry.assessment ~= "" then
metaStr = metaStr .. ", " .. entry.assessment .. " rating"
end
-- Add Importance if it exists
if entry.importance and entry.importance ~= "" then
metaStr = metaStr .. ", " .. entry.importance .. " importance"
end
-- Cap it: )
metaStr = metaStr .. ")"
-- Format as: Link ''(Metadata)''
local itemText = string.format("%s ''%s''", annotatedLink, metaStr)
list:tag('li'):wikitext(itemText)
end
return tostring(list)
end
return p
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.