« Module:ZoteroItem » : différence entre les versions

De alcolois
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
Aucun résumé des modifications
 
(4 versions intermédiaires par le même utilisateur non affichées)
Ligne 17 : Ligne 17 :
end
end
return data.json
return data.json
end
-- Fonction utilitaire de formatage
local function htmlDecode(str)
if not str then return nil end
return str
:gsub(":", ":")
:gsub("[", "[")
:gsub("]", "]")
:gsub(""", '"')
:gsub("&", "&")
end
end


Ligne 42 : Ligne 53 :
function p.alternateLink(frame)
function p.alternateLink(frame)
local data = fetchZoteroData(frame.args[1])
local data = fetchZoteroData(frame.args[1])
if not data or not data.links or not data.links.alternate then return "" end
if data and data.links and data.links.alternate and data.links.alternate.href then
return mw.text.nowiki(data.links.alternate.href or "")
return htmlDecode(data.links.alternate.href)
end
return ""
end
end


Ligne 91 : Ligne 104 :


function p.url(frame)
function p.url(frame)
return getField(frame, { "data", "url" })
local data = fetchZoteroData(frame.args[1])
end
if data and data.data and data.data.url then
 
return htmlDecode(data.data.url)
function p.accessDate(frame)
end
return getField(frame, { "data", "accessDate" })
return ""
end
end


Ligne 104 : Ligne 117 :
function p.extra(frame)
function p.extra(frame)
return getField(frame, { "data", "extra" })
return getField(frame, { "data", "extra" })
end
local function trimDate(dateStr)
if type(dateStr) == "string" then
return mw.text.nowiki(dateStr:sub(1, 10))
end
return ""
end
end


function p.dateAdded(frame)
function p.dateAdded(frame)
return getField(frame, { "data", "dateAdded" })
local data = fetchZoteroData(frame.args[1])
if not data or not data.data or not data.data.dateAdded then return "" end
return trimDate(data.data.dateAdded)
end
end


function p.dateModified(frame)
function p.dateModified(frame)
return getField(frame, { "data", "dateModified" })
local data = fetchZoteroData(frame.args[1])
if not data or not data.data or not data.data.dateModified then return "" end
return trimDate(data.data.dateModified)
end
 
function p.accessDate(frame)
local data = fetchZoteroData(frame.args[1])
if not data or not data.data or not data.data.accessDate then return "" end
return trimDate(data.data.accessDate)
end
end


Ligne 193 : Ligne 223 :


return table.concat(urls, ", ")
return table.concat(urls, ", ")
end
function p.notes(frame)
local itemKey = frame.args[1]
if not itemKey or itemKey == "" then return "" end
local url = string.format(
"https://api.zotero.org/groups/4893620/items/%s/children?format=json&include=data",
mw.uri.encode(itemKey)
)
local data, errors = mw.ext.externalData.getExternalData{
url = url,
format = "JSON",
data = { notes = "__json" }
}
if errors or not data or not data.notes then
return ""
end
local output = {}
for _, item in ipairs(data.notes) do
if item.data and item.data.itemType == "note" then
local rawHtml = item.data.note or ""
local url = (item.links and item.links.alternate and item.links.alternate.href) or ""
-- Étape 1 : supprimer tout sauf les balises autorisées
-- Autorisé : <p>, </p>, <h1>, </h1>, <a href="...">, </a>
local cleaned = rawHtml:gsub('<(.-)>', function(tag)
-- Cas <a href="...">
if tag:match('^a%s+href=') then
return "<" .. tag .. ">"
end
-- Cas </a>, <p>, </p>, <h1>, </h1>
if tag == "/a" or tag == "p" or tag == "/p" or tag == "h1" or tag == "/h1" then
return "<" .. tag .. ">"
end
-- Sinon : supprimer
return ""
end)
if cleaned ~= "" then
table.insert(output, cleaned)
end
if url ~= "" then
table.insert(output, url)
end
end
end
return table.concat(output, "\n\n")
end
end
return p
return p

Dernière version du 12 juin 2025 à 20:34

La documentation pour ce module peut être créée à Module:ZoteroItem/doc

local p = {}

-- Fonction utilitaire pour récupérer les données JSON Zotero
local function fetchZoteroData(itemKey)
	if not itemKey or itemKey == "" then return nil end
	local url = string.format(
		"https://api.zotero.org/groups/4893620/items/%s?format=json&include=data",
		itemKey
	)
	local data, errors = mw.ext.externalData.getExternalData{
		url = url,
		format = "JSON",
		data = { json = "__json" }
	}
	if errors or not data or not data.json then
		return nil
	end
	return data.json
end

-- Fonction utilitaire de formatage
local function htmlDecode(str)
	if not str then return nil end
	return str
		:gsub("&#58;", ":")
		:gsub("&#91;", "[")
		:gsub("&#93;", "]")
		:gsub("&#34;", '"')
		:gsub("&amp;", "&")
end

-- Fonction générique pour retourner un champ simple
local function getField(frame, path)
	local itemKey = frame.args[1]
	local data = fetchZoteroData(itemKey)
	if not data then return "" end
	local current = data
	for _, key in ipairs(path) do
		if type(current) ~= "table" or current[key] == nil then
			return ""
		end
		current = current[key]
	end
	return mw.text.nowiki(tostring(current))
end

-- Fonctions individuelles

function p.key(frame)
	return getField(frame, { "key" })
end

function p.alternateLink(frame)
	local data = fetchZoteroData(frame.args[1])
	if data and data.links and data.links.alternate and data.links.alternate.href then
		return htmlDecode(data.links.alternate.href)
	end
	return ""
end

function p.caseName(frame)
	return getField(frame, { "data", "caseName" })
end

function p.abstractNote(frame)
	return getField(frame, { "data", "abstractNote" })
end

function p.court(frame)
	return getField(frame, { "data", "court" })
end

function p.dateDecided(frame)
	return getField(frame, { "data", "dateDecided" })
end

function p.docketNumber(frame)
	return getField(frame, { "data", "docketNumber" })
end

function p.reporter(frame)
	return getField(frame, { "data", "reporter" })
end

function p.reporterVolume(frame)
	return getField(frame, { "data", "reporterVolume" })
end

function p.firstPage(frame)
	return getField(frame, { "data", "firstPage" })
end

function p.history(frame)
	return getField(frame, { "data", "history" })
end

function p.language(frame)
	return getField(frame, { "data", "language" })
end

function p.shortTitle(frame)
	return getField(frame, { "data", "shortTitle" })
end

function p.url(frame)
	local data = fetchZoteroData(frame.args[1])
	if data and data.data and data.data.url then
		return htmlDecode(data.data.url)
	end
	return ""
end

function p.rights(frame)
	return getField(frame, { "data", "rights" })
end

function p.extra(frame)
	return getField(frame, { "data", "extra" })
end

local function trimDate(dateStr)
	if type(dateStr) == "string" then
		return mw.text.nowiki(dateStr:sub(1, 10))
	end
	return ""
end

function p.dateAdded(frame)
	local data = fetchZoteroData(frame.args[1])
	if not data or not data.data or not data.data.dateAdded then return "" end
	return trimDate(data.data.dateAdded)
end

function p.dateModified(frame)
	local data = fetchZoteroData(frame.args[1])
	if not data or not data.data or not data.data.dateModified then return "" end
	return trimDate(data.data.dateModified)
end

function p.accessDate(frame)
	local data = fetchZoteroData(frame.args[1])
	if not data or not data.data or not data.data.accessDate then return "" end
	return trimDate(data.data.accessDate)
end

-- Créateurs (formaté en liste de noms complets)
function p.creators(frame)
	local itemKey = frame.args[1]
	local data = fetchZoteroData(itemKey)
	if not data or not data.data or not data.data.creators then return "" end
	local authors = {}
	for _, c in ipairs(data.data.creators) do
		local name = c.name or ((c.firstName or "") .. " " .. (c.lastName or ""))
		if name ~= "" then
			table.insert(authors, mw.text.nowiki(name))
		end
	end
	return table.concat(authors, ", ")
end

-- Tags
function p.tags(frame)
	local itemKey = frame.args[1]
	local data = fetchZoteroData(itemKey)
	if not data or not data.data or not data.data.tags then return "" end
	local tags = {}
	for _, t in ipairs(data.data.tags) do
		if t.tag then
			table.insert(tags, mw.text.nowiki(t.tag))
		end
	end
	return table.concat(tags, ", ")
end

-- Collections
function p.collections(frame)
	local itemKey = frame.args[1]
	local data = fetchZoteroData(itemKey)
	if not data or not data.data or not data.data.collections then return "" end
	if #data.data.collections == 0 then return "" end
	local out = {}
	for _, id in ipairs(data.data.collections) do
		table.insert(out, mw.text.nowiki(id))
	end
	return table.concat(out, ", ")
end

-- Relations
function p.relations(frame)
	local itemKey = frame.args[1]
	local groupName = "alcolois"
	local groupId = "4893620"

	local data = fetchZoteroData(itemKey)
	if not data or not data.data or not data.data.relations then return "" end

	local rel = data.data.relations
	local urls = {}

	for k, v in pairs(rel) do
		if k == "dc:relation" then
			if type(v) == "string" then
				local id = v:match("/items/(%w+)$")
				if id then
					table.insert(urls, string.format(
						"https://www.zotero.org/groups/%s/%s/items/%s",
						groupId, groupName, id
					))
				end
			elseif type(v) == "table" then
				for _, url in ipairs(v) do
					local id = tostring(url):match("/items/(%w+)$")
					if id then
						table.insert(urls, string.format(
							"https://www.zotero.org/groups/%s/%s/items/%s",
							groupId, groupName, id
						))
					end
				end
			end
		end
	end

	return table.concat(urls, ", ")
end
function p.notes(frame)
	local itemKey = frame.args[1]
	if not itemKey or itemKey == "" then return "" end

	local url = string.format(
		"https://api.zotero.org/groups/4893620/items/%s/children?format=json&include=data",
		mw.uri.encode(itemKey)
	)

	local data, errors = mw.ext.externalData.getExternalData{
		url = url,
		format = "JSON",
		data = { notes = "__json" }
	}

	if errors or not data or not data.notes then
		return ""
	end

	local output = {}

	for _, item in ipairs(data.notes) do
		if item.data and item.data.itemType == "note" then
			local rawHtml = item.data.note or ""
			local url = (item.links and item.links.alternate and item.links.alternate.href) or ""

			-- Étape 1 : supprimer tout sauf les balises autorisées
			-- Autorisé : <p>, </p>, <h1>, </h1>, <a href="...">, </a>
			local cleaned = rawHtml:gsub('<(.-)>', function(tag)
				-- Cas <a href="...">
				if tag:match('^a%s+href=') then
					return "<" .. tag .. ">"
				end
				-- Cas </a>, <p>, </p>, <h1>, </h1>
				if tag == "/a" or tag == "p" or tag == "/p" or tag == "h1" or tag == "/h1" then
					return "<" .. tag .. ">"
				end
				-- Sinon : supprimer
				return ""
			end)

			if cleaned ~= "" then
				table.insert(output, cleaned)
			end
			if url ~= "" then
				table.insert(output, url)
			end
		end
	end

	return table.concat(output, "\n\n")
end
return p