« 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
 
(Une version intermédiaire par le même utilisateur non affichée)
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])
if data and data.data and data.data.url then
return htmlDecode(data.data.url)
end
return ""
end
end


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


-- Nettoyage : ne garder que <p> et <h1> (supprime tout le reste)
-- Étape 1 : supprimer tout sauf les balises autorisées
noteHtml = mw.ustring.gsub(noteHtml, "</?(%w+)[^>]*>", function(tag)
-- Autorisé : <p>, </p>, <h1>, </h1>, <a href="...">, </a>
if tag == "p" or tag == "h1" then
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 .. ">"
return "<" .. tag .. ">"
elseif tag == "/p" or tag == "/h1" then
return "</" .. tag:sub(2) .. ">"
else
return ""
end
end
-- Sinon : supprimer
return ""
end)
end)


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

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