:Module:Wikidata table

local p = {}

local debugging = false

local sep = ", " -- separator for multiple values of same property, changed from "
"

local sep2 = "
" -- separator for values of different properties

local maxrefs = 3 -- maximum number of references displayed for each statement

-- Internationalisation

local currentlang = mw.language.getContentLanguage()

local i18n = {

filespace = "File",

editonwikidata = "Edit this on Wikidata",

ordinal = {

[1] = "st",

[2] = "nd",

[3] = "rd",

["default"] = "th"

},

}

local months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }

local mnths = {}

for idx, val in ipairs(months) do

mnths[idx] = val:sub(1,3)

end

-- makeOrdinal needs to be internationalised along with the above i18n

-- takes cardinal number as a numeric and returns the ordinal as a string

-- we need three exceptions in English for 1st, 2nd, 3rd, 21st, .. 31st, etc.

-------------------------------------------------------------------------------

p.makeOrdinal = function(cardinal)

local card = tonumber(cardinal)

if not card then return cardinal end

local ordsuffix = i18n.ordinal.default

if card % 10 == 1 then

ordsuffix = i18n.ordinal[1]

elseif card % 10 == 2 then

ordsuffix = i18n.ordinal[2]

elseif card % 10 == 3 then

ordsuffix = i18n.ordinal[3]

end

-- In English, 1, 21, 31, etc. use 'st', but 11, 111, etc. use 'th'

-- similarly for 12 and 13, etc.

if (card % 100 == 11) or (card % 100 == 12) or (card % 100 == 13) then

ordsuffix = i18n.ordinal.default

end

return card .. ordsuffix

end

local unitsymbol = {

Q218593 = "in",

Q3710 = "ft",

Q482798 = "yd",

Q253276 = "mi",

Q93318 = "nmi",

Q11573 = "m",

Q174728 = "cm",

Q174789 = "mm",

Q828224 = "km",

Q81292 = "acres",

Q35852 = "ha",

Q712226 = "km2"

}

-- prefixes for particular qualifiers

local prefix = {

P580 = "from ",

P582 = "until ",

}

-- external ids which have a formatter url (P1630)

local formaturl = {

P3563 = "https://wikidata-externalid-url.toolforge.org/?url=https%3A%2F%2Fmsi.nga.mil%2FqueryResults%3Fpublications%2Fngalol%2Flights-buoys%3Fvolume%3D%251%26featureNumber%3D%252%26includeRemovals%3Dfalse%26output%3Dhtml&exp=(%5Cd%7B3%7D)-(.*)&id=$1", -- NGA number

P613 = "http://nearby.org.uk/coord.cgi?p=$1", -- OS grid reference

P373 = "https://commons.wikimedia.org/wiki/Category:$1", -- Commons category

P11235 = "http://damnet.or.jp/cgi-bin/binranA/enAll.cgi?db4=$1", -- Dams in Japan

P11627 = "https://www.ibiblio.org/lighthouse/$1.htm", -- Lighthouse Directory

}

-- date format default to dmy

local df = "dmy"

-- fallbacks for common properties:

-- property-to-fallback-from = "property-to-fallback-to"

local fallback = {

P276 = "P131",

P571 = "P1619",

P729 = "P1619",

P4755 = "P296",

P18 = "P8592"

}

local statedIDs = {

Q36578 = {"GND", name=1},

Q547473 = {"MacTutor", name="id"},

Q19938912 = {"BNF", name=1},

Q6973052 = {"National Heritage List for England", name="num"},

Q19842847 = {"Historic Scotland listed building number", name=1}

}

-- error messages

local function errmsg(txt)

if debugging then

return "Error: " .. txt

else

return nil

end

end

-- formats the first character of linked item to uppercase

local function ucf(lnk)

local tbl = mw.text.split( lnk, "|", true )

local ret

if tbl[2] then -- piped link

tbl[2] = tbl[2]:gsub("^(%l)", mw.ustring.upper)

ret = table.concat(tbl, "|")

elseif lnk:sub(1,2) == "[[" then -- unpiped link

ret = lnk:gsub("^(%[%[%l)", mw.ustring.upper)

else -- unlinked

ret = lnk:gsub("^(%l)", mw.ustring.upper)

end

return ret

end

-- entrypoint for invoke

function p.ucf(frame)

return ucf(frame.args.text or "")

end

-- return a number rounded to a precision

local function decimalprecision(x, prec)

local s = 1

if x < 0 then

x = -x

s = -1

end

-- if prec is not suplied, pick an arbitrary precision

if not tonumber(prec) then prec = 1e-4

elseif prec > 1 then prec = 1

elseif prec < 1e-6 then prec = 1e-6

else prec = 10 ^ math.floor(math.log10(prec))

end

x = math.floor(x / prec + 0.5) * prec * s

-- if it's integral, cast to an integer:

if x == math.floor(x) then x = math.floor(x) end

-- if it's less than 1e-4, it will be in exponent form, so return a string with 6dp

-- 9e-5 becomes 0.000090

if math.abs(x) < 1e-4 then x = string.format("%f", x) end

return x

end

-- creates an icon that links to the relevant Wikidata entity

local function createicon(entityID, propertyID, langcode)

langcode = langcode or ""

if not entityID or entityID == "" then entityID= mw.wikibase.getEntityIdForCurrentPage() end

propertyID = propertyID or ""

local icon = " [["

-- " [[" -> enable Wikidata Bridge

.. i18n.filespace

.. ":OOjs UI icon edit-ltr-progressive.svg |frameless |text-top |10px |alt="

.. i18n.editonwikidata

.. "|link=https://www.wikidata.org/wiki/" .. entityID

if langcode ~= "" then icon = icon .. "?uselang=" .. langcode end

if propertyID ~= "" then icon = icon .. "#" .. propertyID end

icon = icon .. "|" .. i18n.editonwikidata .. "]]"

return icon

end

-- takes a statement tuple supplied from Wikidata and returns any references

function p._getrefs(statement, qid)

if not statement.references then return nil end

local rtbl = {}

local frm = mw.getCurrentFrame()

for idx, ref in ipairs(statement.references) do

if ref.snaks.P854 then -- reference url

local url = ref.snaks.P854[1].datavalue.value

if ref.snaks.P1476 then -- title (monolingual text)

local title

for idx1, titles in ipairs(ref.snaks.P1476) do

if titles.datavalue.value.language == currentlang then

title = titles.datavalue.value.text

local website = ""

if ref.snaks.P248 then

local rqid = ref.snaks.P248[1].datavalue.value.id

local label = mw.wikibase.label(rqid,currentlang)

if label then

local sitelink = mw.wikibase.sitelink(rqid)

if sitelink then

website = "" .. label .. ""

else

website = label

end

end

end

local citeweb = frm:expandTemplate{ title = "Cite web", args = { url=url, title=title, website=website} }

local hash = "WD" .. mw.hash.hashValue("crc32", citeweb)

rtbl[#rtbl+1] = frm:callParserFunction{ name = "#tag:ref", args = { citeweb, name=hash } }

break

end

end

else

local bnf = url:match("https?://data.bnf.fr/ark:/12148/cb([0-9][a-Za-Z0-9]+)") or url:match("https?://catalogue.bnf.fr/ark:/12148/cb([0-9][a-Za-Z0-9]+)")

if bnf then

rtbl[#rtbl+1] = frm:callParserFunction{ name = "#tag:ref", args = { frm:expandTemplate{title="BNF",args={bnf}}, name="bnf"..bnf} }

else

local hash = "WD" .. mw.hash.hashValue("crc32", url)

rtbl[#rtbl+1] = frm:callParserFunction{ name = "#tag:ref", args = { url, name=hash } }

end

end

elseif ref.snaks.P248 then

local rqid = ref.snaks.P248[1].datavalue.value.id

if statedIDs[rqid] then

local template = statedIDs[rqid]

local propid = mw.wikibase.getBestStatements(rqid,"P1687")

propid = propid[1].mainsnak.datavalue.value.id

for num, propdata in ipairs(mw.wikibase.getBestStatements(qid, propid)) do

local property = propdata.mainsnak.datavalue.value

local args = {[template.name] = property}

if rqid == "Q547473" then

args.title = mw.wikibase.label(qid)

end

local result = frm:expandTemplate{title=template[1],args=args}

rtbl[#rtbl+1] = frm:callParserFunction{ name = "#tag:ref", args = { result, name=qid .. propid .. num} }

end

else

local citeq = frm:expandTemplate{ title = "Cite Q", args = { rqid } }

rtbl[#rtbl+1] = frm:callParserFunction{ name = "#tag:ref", args = { citeq, name=rqid } }

end

end

if #rtbl>=maxrefs then break end -- maximum number of references reached

end

return table.concat(rtbl)

end

-- takes a qid and attempts to return a linked name for it

-- otherwise an unlinked name; otherwise the qid

function p._getLink(qid)

local lbl = ""

local slink = mw.wikibase.sitelink(qid)

local label = mw.wikibase.getLabel(qid)

if slink and label then

if slink:lower() == label:lower() then

if label:find("^%u") then -- match label's case

lbl = "" .. slink:gsub("^(%l)", mw.ustring.upper) .. ""

else

lbl = "" .. slink:gsub("^(%u)", mw.ustring.lower) .. ""

end

else

lbl = "" .. label .. ""

end

elseif slink then

lbl = "" .. slink .. ""

elseif label then

lbl = label

else

lbl = qid

end

return lbl

end

-- entrypoint for #invoke getLink

function p.getLink(frame)

local qid = (frame.args.qid or ""):upper()

if qid == "" then return nil end

return p._getLink(qid)

end

-- takes a snak for a time property and returns the date

local function _getDate(snak, prec)

local retval

retval = mw.wikibase.renderSnak(snak)

if prec == 7 then -- century

local num, txt = retval:match("^(%d+)%.(.+)$")

retval = p.makeOrdinal(num) .. txt

elseif prec == 10 then

local m, y, e = retval:match("^(%a+) (%d+)(.*)")

retval = m:sub(1,3) .. " " .. y .. e

elseif prec == 11 then

local d, m, y, e = retval:match("^(%d+) (%a+) (%d+)(.*)")

retval = d .. " " .. m:sub(1,3) .. " " .. y .. e

end

return retval

end

-- takes a qid and a property id and returns the corresponding values or nil

-- maxvals greater than zero sets the maximum number of values to return

-- the string quals contains property ids of qualifiers to be returned ('-' is the separator)

function p._getWD(qid, pid, maxvals, quals, colunit)

maxvals = maxvals or 0

local ret = {}

local sortkey

for idx, prop in ipairs(mw.wikibase.getBestStatements(qid, pid)) do

local retval

if prop.mainsnak.snaktype ~= "value" then

break

end

local dtype = prop.mainsnak.datatype

local dval = prop.mainsnak.datavalue.value

if dtype == "wikibase-item" then

retval = p._getLink(dval.id)

elseif dtype == "monolingualtext" then

retval = dval.text

elseif dtype == "commonsMedia" or dtype == "url" then

retval = dval

elseif dtype == "external-id" or dtype == "string" then

if formaturl[pid] then

retval = "[" .. mw.ustring.gsub(formaturl[pid], "$1", dval) .. " " .. dval .. "]"

else

retval = dval

end

elseif dtype == "time" then

retval = _getDate(prop.mainsnak, dval.precision)

if dval.precision == 11 and df == "mdy" then

local d, m, y, e = retval:match("^(%d+) (%a+) (%d+)(.*)")

retval = m .. " " .. d .. ", " .. y .. e

end

if not sortkey then

sortkey = prop.mainsnak.datavalue.value.time

end

elseif dtype == "quantity" then

local amount = tonumber(dval.amount)

local unit = string.match( dval.unit, "(Q%d+)" )

if unit then

if unit == colunit then -- unit matches default for this column, so do not display unit

retval = amount

else

if unitsymbol[unit] then

if colunit then -- attempt to convert to default unit

local unit_label = mw.wikibase.label(unit) or unitsymbol[unit] or '???'

local colunit_label = mw.wikibase.label(colunit) or unitsymbol[colunit] or '???'

retval = mw.getCurrentFrame():expandTemplate{ title = "cvt", args = {

amount,

unitsymbol[unit],

unitsymbol[colunit],

disp='number'}

} .. mw.getCurrentFrame():expandTemplate{

title="efn",

args = {

name = string.format(

'Converted%s%s',

unitsymbol[unit],

unitsymbol[colunit]

),

[1] = string.format(

'Change in units: quantity in %s has been automatically converted to %s for uniformity.',

unit_label,

colunit_label

)

}

}

else -- show unit and default conversion

retval = mw.getCurrentFrame():expandTemplate{ title = "cvt", args = {amount, unitsymbol[unit]} }

end

else

retval = amount .. " " .. mw.wikibase.getLabel(unit)

end

end

else

retval = amount

end

elseif dtype == "globe-coordinate" then

local lat = decimalprecision(dval.latitude, dval.precision)

local long = decimalprecision(dval.longitude, dval.precision)

retval = ""

.. mw.wikibase.formatValue(prop.mainsnak)

.. ""

else

retval = dval

end

-- get references

retval = retval .. (p._getrefs(prop, qid) or "")

-- get qualifiers

if quals and prop.qualifiers and retval then

local qtbl = {}

for qpid in quals:gmatch("P%d+") do

if prop.qualifiers[qpid] then

for i, qv in ipairs(prop.qualifiers[qpid]) do

if qv.snaktype ~= "value" then break end

local fqv

if qv.datatype == "globe-coordinate" then

fqv = mw.wikibase.formatValue(qv) -- linked

elseif qv.datatype == "time" then

fqv = _getDate(qv, qv.datavalue.value.precision)

if qv.datavalue.value.precision == 11 then -- trim to month

fqv = fqv:match("%d+ (.+)")

end

else

fqv = mw.wikibase.renderSnak(qv) -- plaintext

end

if fqv and fqv ~= "" then

qtbl[#qtbl+1] = (prefix[qpid] or "") .. fqv

end

end

end

end

if #qtbl > 0 then

retval = retval .. " (" .. table.concat(qtbl, " ") .. ")"

end

end

ret[#ret+1] = retval

if maxvals > 0 and #ret >= maxvals then break end

end

if #ret < 1 then

return nil

else

return table.concat(ret, sep),sortkey

end

end

-- entrypoint for #invoke getWD

function p.getWD(frame)

local qid = (frame.args.qid or ""):upper()

if qid == "" then return nil end

local pid = (frame.args.pid or ""):upper()

if pid == "" then return nil end

local maxvals = tonumber(frame.args.maxvals) or 0

local quals = (frame.args.quals or ""):upper()

if quals == "" then quals = nil end

return p._getWD(qid, pid, maxvals, quals)

end

-- make a single table row, one cell per value passed in args.pids

-- each value may be a combination of properties and qualifiers

function p._makerow(args)

local qid = (args.qid or ""):upper():match("Q%d+")

-- qid can be nil if we want a row without wikidata

-- remove whitespace, uppercase, trap nil

args.pids = (args.pids or ""):upper():gsub("%s", "")

if args.pids == "" then return errmsg("missing pids") end

local summary = (args.summary or "")

local linecolor = (args.line or "")

local linestyle = ''

if linecolor ~= "" then

linestyle = 'style="border-top:solid #' .. linecolor .. ';"'

end

local rows

if summary == "" then rows=1 else rows=2 end

local cols = 0

-- collect any parameters c1, c2, etc. as cell replacements; c1+, c2+, etc. as addenda

local cellrep, celladd = {}, {}

for key, value in pairs(args) do

local colr = (type(key) == "string") and tonumber(key:match("^[Cc](%d+)$"))

if colr then

cellrep[colr] = value

end

local cola = (type(key) == "string") and tonumber(key:match("^[Cc](%d+)%+$"))

if cola then

celladd[cola] = value

end

end

if args.refname and args.refname ~= "" then

local c1 = celladd[1] or ""

celladd[1] = c1 .. mw.getCurrentFrame():extensionTag{name = 'ref', args = {name = args.refname}}

end

-- set date format if passed

args.df = args.df or ""

if args.df ~= "" then df = args.df end

-- create the html to return

local out = ""

if cellrep[1] and qid then

out = out .. cellrep[1] .. createicon(qid) .. ""

elseif not qid then

out = out .. (cellrep[1] or " ") .. ""

else

out = out .. ucf(p._getLink(qid)) .. (celladd[1] or "") .. createicon(qid) .. ""

end

-- split args.pids at comma separators into sequence of cellpids (each may be like P12+P34/P456-P789)

local cellpids = mw.text.split(args.pids, ",+")

for c, val in ipairs(cellpids) do

cols = cols+1

if cellrep[c+1] then

out = out .. '' .. cellrep[c+1] .. ''

elseif not qid then

out = out .. ""

elseif val=='SD' then

local short_description = mw.wikibase.getDescription(qid)

if short_description then

short_description = currentlang:ucfirst(short_description)

else

local getShortDescription = require('Module:GetShortDescription' ).main

local sdt = getShortDescription{name = mw.wikibase.sitelink(qid)}

short_description = sdt.explicit or ''

end

out = out .. '' .. short_description .. ''

else

-- separate multiple properties in same cell, sep=+

local ptbl = {} -- sequence of values for one cell

local sortkeyf

for propandquals in mw.text.gsplit(val, "+", true) do

-- for each property, split off property from qualifiers, sep=/

local pid = mw.text.split(propandquals, "/")[1]

local unit = pid:match("%((Q%d+)%)") -- capture unit of quantity if specified

pid = pid:match("P%d+")

local quals = mw.text.split(propandquals, "/")[2]

if pid == "P18" then -- image

local img = p._getWD(qid, "P18", 1)

if not img and fallback["P18"] then

img = p._getWD(qid, fallback["P18"], 1)

end

if img then

ptbl[#ptbl+1] = "100px"

end

else

local wdval,sortkey = p._getWD(qid, pid, 0, quals, unit)

if not wdval and fallback[pid] then

wdval,sortkey = p._getWD(qid, fallback[pid], 0, quals, unit)

end

if not sortkeyf then

sortkeyf = sortkey

end

ptbl[#ptbl+1] = wdval and ucf(wdval)

end

end -- of loop through multiple properties in same cell

if sortkeyf then

sortkeyf = 'data-sort-value="' .. mw.ustring.sub(sortkeyf,2) .. '"'

else

sortkeyf = ''

end

out = out .. '' .. table.concat(ptbl, sep2) .. (celladd[c+1] or "") .. ''

end

end -- of loop through all of the cells in the row

out = out .. ""

if summary ~= "" then

out = out .. "" .. summary .. ""

end

return out

end

-- entry point for #invoke makerow

function p.makerow(frame)

local args = {}

for key, value in pairs(frame:getParent().args) do

args[key] = value

end

for key, value in pairs(frame.args) do

args[key] = value

end

local isdoc

if args.doc and args.doc=="no" then

isdoc = false

else

isdoc = mw.title.getCurrentTitle():inNamespace(10)

end

if isdoc then

args.qid = args.example

return p.doc(args)

else

return p._makerow(args)

end

end

function p.convert(frame)

local args = frame.args

local pargs = frame:getParent().args

local input = args[1] or pargs[1]

local template = args.template or pargs.template

if input == nil then

return nil

end

local resolveEntity = require( "Module:ResolveEntityId" )

local articlelist = mw.text.split(input,"%*%s*")

local qidlist = {}

for i,article in ipairs(articlelist) do

local rawarticle=string.match(article,'%[%[(.+)%|') or string.match(article,'%[%[(.+)%]%]')

if rawarticle then

local qid = resolveEntity._id(rawarticle)

if qid then

qidlist[#qidlist+1] = "{{" .. template .. "|qid=" .. qid.."}}"

else

qidlist[#qidlist+1] = "{{" .. template .. "|qid=|c1="..rawarticle.."}}"

end

end

end

return table.concat(qidlist,"\n")

end

function p.convert2(frame)

local args = frame.args

local pargs = frame:getParent().args

local input = args[1] or pargs[1]

local template = args.template or pargs.template

if input == nil then

return nil

end

local qidlist = mw.text.split(input,"%*%s*")

local out = ""

for i,qid in ipairs(qidlist) do

qid = mw.text.trim(qid)

out = out .. "{{" .. template .. "|qid=" .. qid

local label = mw.wikibase.getLabel(qid)

if label then

out = out .. ""

end

out = out .. "}}\n"

end

return out

end

local function proplink(pid)

local out

if pid == "P1" then

out = "Custom input"

else

out = mw.getCurrentFrame():expandTemplate{ title = 'Wikidata entity link', args = {pid} }

end

return out

end

function p.doc(args)

local pids = args.pids

local article = args.article

local qid = args.qid

local documentation = require('Module:Documentation').main

pids = (pids or ""):upper():gsub("%s", "")

if pids == "" then return errmsg("Missing PIDs") end

local pidtable = {}

for c1,val in ipairs(mw.text.split(pids, ",")) do

pidtable[c1] = {}

for c2,propandquals in ipairs(mw.text.split(val, "+")) do

pidtable[c1][c2] = {}

pidtable[c1][c2].property = mw.text.split(propandquals, "/")[1]

pidtable[c1][c2].unit = pidtable[c1][c2].property:match("%((Q%d+)%)")

if pidtable[c1][c2].property~='SD' then

pidtable[c1][c2].property = pidtable[c1][c2].property:match("P%d+")

end

local quals = mw.text.split(propandquals, "/")[2]

if quals then

pidtable[c1][c2].quals = {}

for qpid in quals:gmatch("P%d+") do

pidtable[c1][c2].quals[1] = qpid

end

end

end

end

local function unit(qid)

if qid then

local unit = mw.wikibase.sitelink(qid)

if unit then

unit = "" .. unitsymbol[qid] .. ""

else

unit = unitsymbol[qid]

end

return " (in " .. unit .. ")"

else

return ""

end

end

local out = "This template will retrieve certain data from Wikidata for use in a table in an article. It is a wrapper template for Module:Wikidata table function makerow, using predefined properties.\n\n"

if article then

out = out .. "It was designed for use on " .. article .. " but may also be used on other articles. (Search)\n"

end

out = out .. "

Usage

"

out = out .. "The data that is displayed in each column is as follows:"

out = out .. '

'

for c = 1,#pidtable+1 do

out = out .. "

"

end

out = out .. "

"

for c1 = 1,#pidtable do

out = out .. "

"

end

out = out .. "

Column " .. c .. "
Label "

for c2 = 1,#pidtable[c1] do

if pidtable[c1][c2].property=='SD' then

out = out .. 'Short description'

else

out = out .. proplink(pidtable[c1][c2].property) .. unit(pidtable[c1][c2].unit)

if pidtable[c1][c2].quals then

out = out .. " qualified by "

for c3 = 1,#pidtable[c1][c2].quals do

out = out .. proplink(pidtable[c1][c2].quals[c3])

end

end

end

out = out .. "
"

end

out = out .. "

"

if qid then

out = out .. "

Example

The Wikidata QID for "

local sitelink = mw.wikibase.getSitelink(qid)

if sitelink then

out = out .. "" .. sitelink .. ""

else

out = out .. mw.wikibase.getLabel(qid)

end

out = out .. " is " .. qid .. ". Typing the following:
"

out = out .. "{{" .. mw.title.getCurrentTitle().text .. "|qid=" .. qid .. "}}
produces"

out = out .. '

'

for c = 1,#pidtable do

local proplabel

if pidtable[c][1].property == "P1" then

proplabel = "Column " .. c+1

elseif pidtable[c][1].property=='SD' then

proplabel = 'Short description'

else

proplabel = currentlang:ucfirst(mw.wikibase.getLabel(pidtable[c][1].property)) .. unit(pidtable[c][1].unit)

end

out = out .. "

"

end

out = out .. "

" .. p._makerow(args) .. "
Name " .. proplabel .. "
"

end

out = out .. "

Notes

\n"

out = out .. "* The table caption, column headings, etc. need to be added manually.\n"

out = out .. "* Please be careful about making changes to this template, as corresponding changes will need to be made to the column headings on "

if article then

out = out .. "" .. article .. " and any other "

else

out = out .. "any "

end

out = out .. "article using it. (Search)\n"

out = out .. "

Overriding columns

"

out = out .. "It is possible to override or append to data values obtained from Wikidata in any column in the table.\n"

out = out .. "* To completely override column n with some custom content, use parameter cn=\n"

out = out .. "*: For example, to replace column 5 with the number 1957 use c5=1957\n"

out = out .. "* To append some custom content to the end of column n use parameter cn+=\n"

out = out .. "*: For example, to add a footnote to column 6 use c6+={{efn|This value is approximate.}}\n"

out = out .. "

Add named reference

"

out = out .. "If you define references in a list then you can cite one of these by using the parameter refname. This will add a reference to column 1 directly after the label.\n"

out = out .. 'For example you can define a reference called Smith1 by using

{{reflist|refs=\nreference\n}}
\n'

out = out .. "Then use refname=Smith1"

if qid then

out = out .. "

References

" .. mw.getCurrentFrame():expandTemplate{title='Reflist'}

end

out = out .. "

TemplateData

"

local td = '{"params": {"qid": {"label": "QID", "description": "Enter the Wikidata QID, which is a number beginning with Q. You can also add the name of the item as an HTML comment.","example": "'

if qid then

td = td .. qid .. ''

else

td = td .. 'Q1234567'

end

td = td .. '","type": "string","suggested": true}'

td = td .. ',"refname": {"label": "Add named reference","description": "Add a named reference defined in a list","type": "string","example": "ref1"}'

td = td .. ',"c1": {"label": "Override label","description": "Override the label (column 1) with this value","type": "content"}'

td = td .. ',"c1+": {"label": "Append to label","description": "Append this content to the label (column 1)","type": "content"}'

for c = 1,#pidtable do

if pidtable[c][1].property == "P1" then

td = td .. ',"c' .. c+1 .. '": {"label": "Define column ' .. c+1 .. '","description": "Define column ' .. c+1 .. ' with this content","type": "content"}'

elseif pidtable[c][1].property~='SD' then

local label = mw.wikibase.getLabel(pidtable[c][1].property)

td = td .. ',"c' .. c+1 .. '": {"label": "Override ' .. label .. '","description": "Override the ' .. label .. ' (column ' .. c+1 .. ') with this content","type": "content"}'

td = td .. ',"c' .. c+1 .. '+": {"label": "Append to ' .. label .. '","description": "Append this content to the ' .. label .. ' (column ' .. c+1 .. ')","type": "content"}'

end

end

td = td .. '},"description": "This template reads some data from Wikidata while also allowing an editor to override or append their own content.","format": "inline"}'

return documentation{content = out .. mw.getCurrentFrame():extensionTag{ name = 'templatedata', content = td}}

end

return p