Module:Tabular data
![]() | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module provides basic functions for interacting with tabular data on Wikimedia Commons.
cell
Returns the value of the cell at the given row index and column name.
Usage: {{#invoke:Tabular data|cell|Page name.tab|output_row=Index of row to output|output_column=Name of column to output}}
A row index of 1
refers to the first row in the table. A row index of -1
refers to the last row in the table. It is an error to specify a row index of 0
.
Examples
Latest death toll in c:Data:COVID-19 cases in Santa Clara County, California.tab (regardless of when the table was last updated):
Lua error at line 23: attempt to compare number with string.
lookup
Returns the value of the cell(s) in one or more output columns of the row matching the search key and column.
This function is reminiscent of LOOKUP()
macros in popular spreadsheet applications, except that the search key must match exactly. (On the other hand, this means the table does not need to be sorted.)
Usage: {{#invoke:Tabular data|lookup|Page name.tab|search_value=Value to find in column|search_column=Name of column to search in|output_column=Name of column to output|output_column2=Name of another column to output|output_columnn=…|output_format=String format to format the output}}
If multiple columns are output without an explicit string format, this function formats the output as a human-readable list.
Some may find {{Tabular query}} (which uses this module) an intuitive way to obtain cell data as it resembles a simple SQL query.
Parameters
|1=
- Page name on Commons with extension but no namespace
|search_value=
or|search_pattern=
- Value to find or pattern to match in column
|search_column=
- Name of column to search in
|occurrence=
- Index of the match to output in case of multiple matching rows. A row index of
1
refers to the first matching row. A row index of-1
refers to the last matching row. It is an error to specify a row index of0
. |output_column=
or|output_column1=
,|output_column2=
, ...- Names of columns to output
|output_format=
- String format to format the output
Examples
Total confirmed case count in c:Data:COVID-19 cases in Santa Clara County, California.tab on the day that the county issued a stay-at-home order:
{{#invoke:Tabular data|lookup
|search_column=date
|output_column=cases
|search_value=2020-03-16
|COVID-19 cases in Santa Clara County, California.tab}}
The last day that a hundred or more patients with COVID-19 were in the hospital in c:Data:COVID-19 cases in Solano County, California.tab:
{{#invoke:Tabular data|lookup
|search_pattern=%d%d%d
|search_column=hospitalized
|output_column=date
|occurrence=-1
|COVID-19 cases in Solano County, California.tab}}
Total number of administrators on all Wikimedia wikis using c:Data:Wikipedia statistics/data.tab:
{{#invoke:Tabular data|lookup
|search_column=site
|output_column=admins
|search_value=total.all
|Wikipedia statistics/data.tab}}
Number of administrators and users on all Wikimedia wikis using c:Data:Wikipedia statistics/data.tab:
{{#invoke:Tabular data|lookup
|output_format=%d out of %d users are administrators
|search_column=site
|output_column2=users
|output_column=admins
|search_value=total.all
|Wikipedia statistics/data.tab}}
Note: Wikipedia statistics are shown as an illustration only. In practice, there is a high-performance module {{NUMBEROF}}
to access Wikipedia statistics.
wikitable
Returns the entire data table as a (rather plain) table.
Usage: {{#invoke:Tabular data|wikitable|Page name.tab}}
Examples
COVID-19 statistics in Santa Clara County, California
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{#invoke:Tabular data|wikitable
|COVID-19 cases in Santa Clara County, California.tab}}
|
Implementation notes
The implementation of this function incorporates {{n/a}} (to represent null values), {{yes}} (true), and {{no}} (false). The templates themselves cannot be reused because they are incompatible with the mw.html
library, which builds the table using an HTML DOM instead of pure wikitext.
Internationalization
You can most likely port this template to a wiki in another language without making major modifications. The wikitable
function automatically localizes the table's description, column titles, and license name into the wiki's content language. It also formats numbers according to the content language. However, you should localize the cells representing true
, false
, and null
by changing the values in the messages
, bgColors
, and colors
variables to match the wiki's own {{yes}}, {{no}}, and {{n/a}} templates, respectively.
See also
- {{NUMBEROF}}
- {{Last tab}} and {{Date tab}}
- sv:Template:Json2table – shows a complete table (based on sv:Module:Json2table, in turn based on a deleted module)
- Template:Wdtable row – fetches a table row from Wikidata in realtime
- Template:Wikidata list – uses a bot to periodically fetch a complete table from Wikidata
local p = {}
local lang = mw.getContentLanguage()
--- Returns the value of the cell at the given row index and column name.
--- A row index of 1 refers to the first row in the table. A row index of -1
--- refers to the last row in the table. It is an error to specify a row index
--- of 0.
--- Usage: {{#invoke: Module:Sandbox/Mxn/Tabular data | lookup | Table name | output_row = Index of row to output | output_column = Name of column to output }}
function p.cell(frame)
local data = mw.ext.data.get(frame.args[1])
local rowIdx = frame.args.output_row
local outputColumnName = frame.args.output_column
local outputColumnIdx
for i, field in ipairs(data.schema.fields) do
if field.name == outputColumnName then
outputColumnIdx = i
break
end
end
assert(outputColumnIdx, "Output column “%s” not found.", outputColumnName)
if rowIdx > 0 then
rowIdx = (rowIdx - 1) % #data.data + 1
elseif rowIdx < 0 then
rowIdx = rowIdx % #data.data + 1
else
error("0 is not a valid row index.")
end
return data.data[rowIdx][searchColumnIdx]
end
--- Returns the value of the cell in the given output column of the row matching
--- the search key and column.
--- Reminiscent of LOOKUP() macros in popular spreadsheet applications, except
--- that the search key must match exactly. (On the other hand, this means the
--- table does not need to be sorted.)
--- Usage: {{#invoke: Module:Sandbox/Mxn/Tabular data | lookup | Table name | search_value = Value to find in column | search_column = Name of column to search in | output_column = Name of column to output }}
function p.lookup(frame)
local data = mw.ext.data.get(frame.args[1])
local searchValue = frame.args.search_value
local searchColumnName = frame.args.search_column
local outputColumnName = frame.args.output_column
local searchColumnIdx
local outputColumnIdx
for i, field in ipairs(data.schema.fields) do
if field.name == searchColumnName then
searchColumnIdx = i
end
if field.name == outputColumnName then
outputColumnIdx = i
end
if searchColumnIdx and outputColumnIdx then
break
end
end
assert(searchColumnIdx, "Search column “%s” not found.", searchColumnName)
assert(outputColumnIdx, "Output column “%s” not found.", outputColumnName)
for i, record in ipairs(data.data) do
if record[searchColumnIdx] == searchValue then
return record[outputColumnIdx]
end
end
end
--- Returns a tabular data page as a wikitext table.
--- Usage: {{#invoke: Module:Sandbox/Mxn/Tabular data | wikitable | Table name }}
function p.wikitable(frame)
local data = mw.ext.data.get(frame.args[1])
local datatypes = {}
local htmlTable = mw.html.create("table")
:addClass("wikitable sortable")
htmlTable
:tag("caption")
:wikitext(data.description)
local headerRow = htmlTable
:tag("tr")
for i, field in ipairs(data.schema.fields) do
headerRow
:tag("th")
:attr("scope", "col")
:attr("data-sort-type", datatypes[j] == "text" and "string" or datatypes[j])
:wikitext(field.title)
datatypes[i] = field.type
end
for i, record in ipairs(data.data) do
local row = htmlTable:tag("tr")
for j = 1, #data.schema.fields do
local cell = row:tag("td")
if record[j] then
local formattedData = record[j]
if datatypes[j] == "number" then
formattedData = lang:formatNum(formattedData)
cell:attr("align", "right")
end
cell:wikitext(formattedData)
else
cell
:addClass("mw-tabular-value-null")
:addClass("table-na")
:css({
background = "#ececec",
color = "#2c2c2c",
["vertical-align"] = "middle",
["text-align"] = "center",
})
:wikitext("N/A")
end
end
end
local footer = htmlTable
:tag("tr")
:tag("td")
:addClass("sortbottom")
:attr("colspan", #data.schema.fields)
footer:wikitext(data.sources)
footer:tag("br")
local licenseText = mw.message.new("Jsonconfig-license",
mw.ustring.format("[%s %s]", data.license.url, data.license.text))
footer
:tag("i")
:wikitext(tostring(licenseText))
return htmlTable
end
return p