Difference between revisions of "Module:Cite Q/sandbox"

From blackwiki
Jump to navigation Jump to search
test>Mike Peel
(sync with master version)
m (11 revisions imported)
 
(8 intermediate revisions by 5 users not shown)
Line 28: Line 28:
 
local function get_name_list (nl_type, args, qid, wdl)
 
local function get_name_list (nl_type, args, qid, wdl)
 
local propertyID = "P50"
 
local propertyID = "P50"
 +
local fallbackID = "P2093" -- author name string
 
 
 
if 'author' == nl_type then
 
if 'author' == nl_type then
 
propertyID = 'P50'; -- for authors
 
propertyID = 'P50'; -- for authors
 +
fallbackID = 'P2093';
 
elseif 'editor' == nl_type then
 
elseif 'editor' == nl_type then
 
propertyID = 'P98'; -- for editors
 
propertyID = 'P98'; -- for editors
 +
fallbackID = nil;
 
else
 
else
 
return; -- not specified so return
 
return; -- not specified so return
Line 42: Line 45:
 
if wdl and (#wdl > 0) then
 
if wdl and (#wdl > 0) then
 
wdl = wdl:lower()
 
wdl = wdl:lower()
if (wdl == "false") or (wdl == "no") or (wdl == "0") then
+
wdl = (wdl == "false") or (wdl == "no") or (wdl == "0")
wdl = false
 
else
 
wdl = true
 
end
 
 
else
 
else
 
-- wdl is empty, so
 
-- wdl is empty, so
Line 52: Line 51:
 
end
 
end
 
 
local entity, props
 
 
local entity = mw.wikibase.getEntity(qid)
 
local entity = mw.wikibase.getEntity(qid)
 +
local props = nil
 +
local fallback = nil
 
if entity and entity.claims then
 
if entity and entity.claims then
 
props = entity.claims[propertyID]
 
props = entity.claims[propertyID]
else
+
if fallbackID then
-- there's no such entity or no claims for the entity
+
fallback = entity.claims[fallbackID]
return nil
+
end
 
end
 
end
 
 
-- Make sure it actually has the property requested
+
-- Make sure it actually has at least one of the properties requested
if not props or not props[1] then  
+
if not (props and props[1]) and not (fallback and fallback[1]) then  
 
return nil
 
return nil
 
end
 
end
Line 71: Line 71:
 
local out = {}
 
local out = {}
 
local link = {}
 
local link = {}
if props[1].mainsnak.datavalue.type == "wikibase-entityid" then
+
local maxpos = 0
-- it's wiki-linked value, so output as link if possible
+
if props and props[1] then
 
for k, v in pairs(props) do
 
for k, v in pairs(props) do
 
local qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
 
local qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
Line 82: Line 82:
 
label = qnumber
 
label = qnumber
 
end
 
end
 +
local position = maxpos + 1 -- Default to 'next' author.
 +
-- use P1545 (series ordinal) instead of default position.
 +
if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
 +
position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
 +
end
 +
maxpos = math.max(maxpos, position)
 
if sitelink then
 
if sitelink then
 
-- just the plain name,
 
-- just the plain name,
 
-- but keep a record of the links, using the same index
 
-- but keep a record of the links, using the same index
out[#out + 1] = label
+
out[position] = label
link[#out] = sitelink
+
link[position] = sitelink
 
else
 
else
 
-- no sitelink, so check first for a redirect with that label
 
-- no sitelink, so check first for a redirect with that label
local artitle = mw.title.new(label, 0)
+
-- this code works, but causes the article to appear in WhatLinksHere for the possible destination, so remove
if artitle.id > 0 then
+
-- local artitle = mw.title.new(label, 0)
if artitle.isRedirect then
+
-- if artitle.id > 0 then
 +
-- if artitle.isRedirect then
 
-- no sitelink,
 
-- no sitelink,
 
-- but there's a redirect with the same title as the label;
 
-- but there's a redirect with the same title as the label;
 
-- so store the link to that
 
-- so store the link to that
out[#out + 1] = label
+
-- out[position] = label
link[#out] = label
+
-- link[position] = label
else
+
-- else
 
-- no sitelink and not a redirect but an article exists with the same title as the label
 
-- no sitelink and not a redirect but an article exists with the same title as the label
 
-- that's probably a dab page, so output the plain label
 
-- that's probably a dab page, so output the plain label
out[#out + 1] = label
+
-- out[position] = label
end
+
-- end
 +
--else
 +
-- no article or redirect with the same title as the label
 +
if wdl then
 +
-- show that there's a Wikidata entry available
 +
out[position] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]&nbsp;<span title='" .. i18n["errors"]["local-article-not-found"] .. "'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>"
 
else
 
else
-- no article or redirect with the same title as the label
+
-- no wikidata links wanted, so just give the plain label
if wdl then
+
out[position] = label
-- show that there's a Wikidata entry available
 
out[#out + 1] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]&nbsp;<span title='" .. i18n["errors"]["local-article-not-found"] .. "'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>"
 
else
 
-- no wikidata links wanted, so just give the plain label
 
out[#out + 1] = label
 
end
 
 
end
 
end
 +
-- end
 
end
 
end
 
end
 
end
else
 
-- not a linkable article title
 
out[#out+1] = entity:formatPropertyValues(propertyID).value
 
 
end
 
end
+
if fallback and fallback[1] then
 +
-- Fallback to name-only authors / editors
 +
for k, v in pairs(fallback) do
 +
local label = v.mainsnak.datavalue["value"]
 +
local position = maxpos + 1 -- Default to 'next' author.
 +
-- use P1545 (series ordinal) instead of default position.
 +
if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
 +
position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
 +
end
 +
maxpos = math.max(maxpos, position)
 +
out[position] = label
 +
end
 +
end
 +
 
 
-- if there's anything to return, then insert the additions in the template arguments table
 
-- if there's anything to return, then insert the additions in the template arguments table
 
-- in the form |author1=firstname secondname |author2= ...
 
-- in the form |author1=firstname secondname |author2= ...
if #out > 0 then
+
-- Renumber, in case we have inconsistent numbering
for k,v in ipairs(out) do -- authorn or editorn
+
local keys = {}
args[nl_type .. k] = v
+
for k,v in pairs(out) do
end
+
keys[#keys+1] = k
for k,v in pairs(link) do -- author-linkn or editor-linkn
+
end
args[nl_type .. '-link' .. k] = v
+
table.sort(keys) -- as they might be out of order
 +
for i, k in ipairs(keys) do
 +
mw.log(i.." "..k.." "..out[k])
 +
args[nl_type .. i] = out[k] -- author-n or editor-n
 +
if link[k] then
 +
args[nl_type .. '-link' .. i] = link[k] -- author-linkn or editor-linkn
 
end
 
end
 
end
 
end
Line 150: Line 172:
 
for k, v in pairs (args) do -- copy named parameters and their values into citeq_args
 
for k, v in pairs (args) do -- copy named parameters and their values into citeq_args
 
if type( k ) == 'string' then -- numbered parameters ignored
 
if type( k ) == 'string' then -- numbered parameters ignored
citeq_args[k] = v;
+
if 'unset' == v then
 +
citeq_args[k] = ''; -- set the parameter to empty string; this may be used later to unset authors and editors
 +
else
 +
citeq_args[k] = v;
 +
end
 
end
 
end
 
end
 
end
+
 
args = frame.args; -- now get frame arguments (from the template wikisource)  
+
args = frame.args; -- now get frame arguments (presets from wikidata in the cite q module #invoke)  
  
 
for k, v in pairs (args) do -- copy args into citeq_args
 
for k, v in pairs (args) do -- copy args into citeq_args
Line 161: Line 187:
 
elseif 'wdlinks' == k then -- don't copy wdlinks
 
elseif 'wdlinks' == k then -- don't copy wdlinks
 
wdl = v; -- save its value
 
wdl = v; -- save its value
else
+
elseif not citeq_args[k] then --
 
citeq_args[k] = v -- but copy everything else
 
citeq_args[k] = v -- but copy everything else
 
end
 
end
Line 167: Line 193:
  
 
if is_set (qid) then
 
if is_set (qid) then
if not is_set (citeq_args.author) and not is_set (citeq_args.author1) then -- if neither are set, try to get authors from wikidata
+
-- if not is_set (citeq_args.author) and not is_set (citeq_args.author1) then -- if neither are set, try to get authors from wikidata
 +
if not (citeq_args['author'] or citeq_args['author1']) then
 
get_name_list ('author', citeq_args, qid, wdl); -- modify citeq_args table with authors from wikidata
 
get_name_list ('author', citeq_args, qid, wdl); -- modify citeq_args table with authors from wikidata
 
end
 
end
  
if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) then -- if neither are set, try to get editors from wikidata
+
-- if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) then -- if neither are set, try to get editors from wikidata
 +
if not (citeq_args['editor'] or citeq_args['editor1']) then
 
get_name_list ('editor', citeq_args, qid, wdl); -- modify citeq_args table with editors from wikidata
 
get_name_list ('editor', citeq_args, qid, wdl); -- modify citeq_args table with editors from wikidata
 
end
 
end

Latest revision as of 12:16, 6 September 2020

Documentation for this module may be created at Module:Cite Q/sandbox/doc

require('Module:No globals')

local citeq = {}

--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.

]]
local function is_set( var )
	return not (var == nil or var == '');
end


--[=[-------------------------< G E T _ N A M E _ L I S T >----------------------------------------------------

get_name_list -- adapted from getAuthors code taken from [[Module:RexxS]]
arguments:
	nl_type - type of name list to fetch: nl_type = 'author' for authors; 'editor' for editors
	args - pointer to the parameter arguments table from the template call
	qid - value from |qid= parameter; the Q-id of the source (book, etc.) in qid
	wdl - value from the |wdlinks= parameter; a boolean passed to enable links to Wikidata when no article exists

returns nothing; modifies the args table

]=]

local function get_name_list (nl_type, args, qid, wdl)
	local propertyID = "P50"
	local fallbackID = "P2093" -- author name string
	
	if 'author' == nl_type then
		propertyID = 'P50';														-- for authors
		fallbackID = 'P2093';
	elseif 'editor' == nl_type then
		propertyID = 'P98';														-- for editors
		fallbackID = nil;
	else
		return;																	-- not specified so return
	end
	
	-- wdlinks is a boolean passed to enable links to Wikidata when no article exists
	-- if "false" or "no" or "0" is passed set it false
	-- if nothing or an empty string is passed set it false
	if wdl and (#wdl > 0) then
		wdl = wdl:lower()
		wdl = (wdl == "false") or (wdl == "no") or (wdl == "0")
	else
		-- wdl is empty, so
		wdl = false
	end
	
	local entity = mw.wikibase.getEntity(qid)
	local props = nil
	local fallback = nil
	if entity and entity.claims then
		props = entity.claims[propertyID]
		if fallbackID then
			fallback = entity.claims[fallbackID]
		end
	end
	
	-- Make sure it actually has at least one of the properties requested
	if not (props and props[1]) and not (fallback and fallback[1]) then 
		return nil
	end
	
	-- So now we have something to return:
	-- table 'out' is going to store the names(s):
	-- and table 'link' will store any links to the name's article
	local out = {}
	local link = {}
	local maxpos = 0
	if props and props[1] then
		for k, v in pairs(props) do
			local qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
			local sitelink = mw.wikibase.sitelink(qnumber)
			local label = mw.wikibase.label(qnumber)
			if label then
				label = mw.text.nowiki(label)
			else
				label = qnumber
			end
			local position = maxpos + 1 -- Default to 'next' author.
			-- use P1545 (series ordinal) instead of default position.
			if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
				position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
			end
			maxpos = math.max(maxpos, position)
			if sitelink then
				-- just the plain name,
				-- but keep a record of the links, using the same index
				out[position] = label
				link[position] = sitelink
			else
				-- no sitelink, so check first for a redirect with that label
				-- this code works, but causes the article to appear in WhatLinksHere for the possible destination, so remove
				-- local artitle = mw.title.new(label, 0)
				-- if artitle.id > 0 then
				--	if artitle.isRedirect then
						-- no sitelink,
						-- but there's a redirect with the same title as the label;
						-- so store the link to that
				--		out[position] = label
				--		link[position] = label
				--	else
						-- no sitelink and not a redirect but an article exists with the same title as the label
						-- that's probably a dab page, so output the plain label
				--		out[position] = label
				--	end
				--else
				-- no article or redirect with the same title as the label
				if wdl then
					-- show that there's a Wikidata entry available
					out[position] = "[[:d:Q" .. v.mainsnak.datavalue.value["numeric-id"] .. "|" .. label .. "]]&nbsp;<span title='" .. i18n["errors"]["local-article-not-found"] .. "'>[[File:Wikidata-logo.svg|16px|alt=|link=]]</span>"
				else
					-- no wikidata links wanted, so just give the plain label
					out[position] = label
				end
				-- end
			end
		end
	end
	if fallback and fallback[1] then
		-- Fallback to name-only authors / editors
		for k, v in pairs(fallback) do
			local label = v.mainsnak.datavalue["value"]
			local position = maxpos + 1 -- Default to 'next' author.
			-- use P1545 (series ordinal) instead of default position.
			if v["qualifiers"] and v.qualifiers["P1545"] and v.qualifiers["P1545"][1] then
				position = tonumber(v.qualifiers["P1545"][1].datavalue.value)
			end
			maxpos = math.max(maxpos, position)
			out[position] = label
		end
	end

	-- if there's anything to return, then insert the additions in the template arguments table
	-- in the form |author1=firstname secondname |author2= ...
	-- Renumber, in case we have inconsistent numbering
	local keys = {}
	for k,v in pairs(out) do
		keys[#keys+1] = k
	end
	table.sort(keys) -- as they might be out of order
	for i, k in ipairs(keys) do
		mw.log(i.." "..k.." "..out[k])
		args[nl_type .. i] = out[k]												-- author-n or editor-n
		if link[k] then
			args[nl_type .. '-link' .. i] = link[k]								-- author-linkn or editor-linkn
		end
	end
end


--[[-------------------------< C I T E _ Q >------------------------------------------------------------------

Takes standard cs1|2 template parameters and passes all to {{citation}}.  If neither of |author= and |author1=
are set, calls get_authors() to try to get an author name-list from wikidata.  The result is passed to 
{{citation}} for rendering.

]]

function citeq.cite_q (frame)
local citeq_args = {};
local qid;
local wdl;

local pframe = frame:getParent()
local args = pframe.args;														-- first get parent frame arguments - these from the template call

	for k, v in pairs (args) do													-- copy named parameters and their values into citeq_args
		if type( k ) == 'string' then											-- numbered parameters ignored
			if 'unset' == v then
				citeq_args[k] = '';												-- set the parameter to empty string; this may be used later to unset authors and editors
			else
				citeq_args[k] = v;
			end
		end
	end

	args = frame.args;															-- now get frame arguments (presets from wikidata in the cite q module #invoke) 

	for k, v in pairs (args) do													-- copy args into citeq_args
		if 'qid' == k then														-- don't copy qid
			qid = v;															-- save its value
		elseif 'wdlinks' == k then												-- don't copy wdlinks
			wdl = v;															-- save its value
		elseif not citeq_args[k] then											-- 
			citeq_args[k] = v													-- but copy everything else
		end
	end

	if is_set (qid) then
--		if not is_set (citeq_args.author) and not is_set (citeq_args.author1) then	-- if neither are set, try to get authors from wikidata
		if not (citeq_args['author'] or citeq_args['author1']) then
			get_name_list ('author', citeq_args, qid, wdl);						-- modify citeq_args table with authors from wikidata
		end

--		if not is_set (citeq_args.editor) and not is_set (citeq_args.editor1) then	-- if neither are set, try to get editors from wikidata
		if not (citeq_args['editor'] or citeq_args['editor1']) then
			get_name_list ('editor', citeq_args, qid, wdl);						-- modify citeq_args table with editors from wikidata
		end
	end

	return frame:expandTemplate{title = 'citation', args = citeq_args};			-- render the citation
end

return citeq