Module:Popular list
Usage
This template implements {{popular list}}, as {{#invoke:Popular list|top7}}.
Parameters
|1=(Required)- The full page name of the "Popular pages" list (e.g.,
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)- The number of entries to display. Defaults to
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
Content Disclaimer
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.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.