Module:ArgumentContent
La documentation pour ce module peut être créée à Module:ArgumentContent/doc
local p = {}
-- ========================
-- I18N
-- ========================
local MESSAGES = {
fr = {
-- Libellés d'UI
justifs_title = "Justifications",
objs_title = "Objections",
edit = "modifier",
edit_justifs_tt = "Modifier la liste des arguments ci-dessous",
edit_objs_tt = "Modifier la liste des objections ci-dessous",
add_argument = "Ajouter un argument",
add_objection = "Ajouter une objection",
add_justif_tt = "Ajouter une justification à l'argument : %s",
add_obj_tt = "Ajouter une objection à l'argument : %s",
none_argument = "''Aucun argument n'a été entré.''",
none_objection = "''Aucune objection n'a été entrée.''",
none_content = "''Aucun contenu n'a été entré.''",
detailed_debate_title = "%s",
-- Termes structurants
prop_page_params = "Paramètres de la page",
prop_argument_content = "Contenu d'argument",
prop_arguments_map = "Carte des arguments",
form_justifications = "Justifications",
form_objections = "Objections",
form_new_argument_title = "Nouveau titre d'argument",
form_type = "type",
type_justification = "Justification",
type_objection = "Objection",
-- Modèles
template_banner = "Bandeau %s",
},
en = {
-- UI labels
justifs_title = "Supporting arguments",
objs_title = "Objections",
edit = "edit",
edit_justifs_tt = "Edit the list of arguments below",
edit_objs_tt = "Edit the list of objections below",
add_argument = "Add an argument",
add_objection = "Add an objection",
add_justif_tt = "Add a supporting argument to: %s",
add_obj_tt = "Add an objection to: %s",
none_argument = "''No argument has been entered.''",
none_objection = "''No objection has been entered.''",
none_content = "''No content has been entered.''",
detailed_debate_title = "%s",
prop_page_params = "Page parameters",
prop_argument_content = "Argument content",
prop_arguments_map = "Arguments map",
form_justifications = "Supporting arguments",
form_objections = "Objections",
form_new_argument_title = "New argument title",
form_type = "type",
type_justification = "Justification",
type_objection = "Objection",
template_banner = "%s banner",
},
es = {
justifs_title = "Justificaciones",
objs_title = "Objeciones",
edit = "editar",
edit_justifs_tt = "Editar la lista de argumentos de abajo",
edit_objs_tt = "Editar la lista de objeciones de abajo",
add_argument = "Añadir un argumento",
add_objection = "Añadir una objeción",
add_justif_tt = "Añadir una justificación a: %s",
add_obj_tt = "Añadir una objeción a: %s",
none_argument = "''No se ha introducido ningún argumento.''",
none_objection = "''No se ha introducido ninguna objeción.''",
none_content = "''No se ha introducido ningún contenido.''",
detailed_debate_title = "%s",
prop_page_params = "Parámetros de la página",
prop_argument_content = "Contenido del argumento",
prop_arguments_map = "Mapa de argumentos",
form_justifications = "Justificaciones",
form_objections = "Objeciones",
form_new_argument_title = "Nuevo título de argumento",
form_type = "tipo",
type_justification = "Justificación",
type_objection = "Objeción",
template_banner = "Aviso %s",
},
}
-- ========================
-- Helpers
-- ========================
local function trim(s)
if type(s) ~= "string" then
return s
end
return s:match("^%s*(.-)%s*$")
end
local function split(s, delim)
if type(s) ~= "string" or s == "" then
return {}
end
if not delim or delim == "" then
return { s }
end
delim = delim or ","
local out = {}
local esc = delim:gsub("(%W)", "%%%1")
for part in (s .. delim):gmatch("(.-)" .. esc) do
table.insert(out, trim(part))
end
return out
end
local function safeIndex(t, idx, default)
if type(t) ~= "table" then
return default
end
local v = t[idx]
if v == nil or v == "" then
return default
end
return v
end
local function toNumber(s, default)
local n = tonumber(s or "")
return n or default or 0
end
local function urlencode(s, mode)
return mw.uri.encode(s or "", mode or "QUERY")
end
local function anchorencode(s)
return mw.uri.anchorEncode(s or "")
end
-- ========================
-- I18N helpers
-- ========================
local function normalizeLang(code)
code = trim(code or "")
if code == "" then
return ""
end
local base = code:match("^([a-zA-Z]+)") or code
return mw.ustring.lower(base)
end
local function getLang(args)
local param = normalizeLang(args.lang or args.language or "")
if param ~= "" and MESSAGES[param] then
return param
end
local contentLang = ""
if mw.getContentLanguage then
local obj = mw.getContentLanguage()
if obj and obj.getCode then
contentLang = normalizeLang(obj:getCode())
end
end
if contentLang ~= "" and MESSAGES[contentLang] then
return contentLang
end
return "en"
end
local function msg(lang, key, ...)
local pack = MESSAGES[lang] or MESSAGES.en
local text = pack[key] or (MESSAGES.en and MESSAGES.en[key]) or key
if select("#", ...) > 0 then
return string.format(text, ...)
end
return text
end
-- ========================
-- SMW access
-- ========================
local function smwShow(frame, page, property)
if not page or page == "" or not property or property == "" then
return ""
end
if mw.smw and type(mw.smw.getQueryResult) == "function" then
local res = mw.smw.getQueryResult{
conditions = { string.format("[[%s]]", page) },
printouts = { property },
parameters = { mainlabel = "-" }
}
if not res or not res.results or not res.results[1] then
return ""
end
local first = res.results[1]
for _, po in ipairs(first.printouts or {}) do
if po.label == property then
local vals = {}
for _, v in ipairs(po.values or {}) do
table.insert(vals, tostring(v.value or v))
end
return table.concat(vals, ", ")
end
end
return ""
else
local txt = frame:callParserFunction("#show", { page, "?" .. property })
return trim(txt or "")
end
end
local function smwAskOneTitle(frame, condition)
if not condition or condition == "" then
return ""
end
if mw.smw and type(mw.smw.getQueryResult) == "function" then
local res = mw.smw.getQueryResult{
conditions = { string.format("[[%s]]", condition) },
printouts = {},
parameters = { mainlabel = "page", limit = 1 }
}
if not res or not res.results or not res.results[1] then
return ""
end
return res.results[1].fulltext or ""
else
local txt = frame:callParserFunction("#ask", {
string.format("[[%s]]", condition),
"link=none",
"limit=1",
})
return trim(txt or "")
end
end
-- ========================
-- Page Forms helpers
-- ========================
local function formlink(frame, form, target, linktext, tooltip)
return frame:callParserFunction("#formlink", {
"form=" .. (form or ""),
"target=" .. (target or ""),
"link text=" .. (linktext or ""),
"tooltip=" .. (tooltip or "")
})
end
local function queryformlink(frame, form, querystring, linktype, linktext, tooltip)
return frame:callParserFunction("#queryformlink", {
"form=" .. (form or ""),
"query string=" .. (querystring or ""),
"link type=" .. (linktype or ""),
"link text=" .. (linktext or ""),
"tooltip=" .. (tooltip or "")
})
end
-- ========================
-- Bandeaux
-- ========================
local function expandBandeaux(frame, csv, lang)
if not csv or csv == "" then
return ""
end
local html = {}
for _, item in ipairs(split(csv, ",")) do
if item and item ~= "" then
local title = msg(lang, "template_banner", item)
table.insert(html, frame:expandTemplate{
title = title,
args = { item }
})
end
end
return table.concat(html, " ")
end
-- ========================
-- Rendu principal
-- ========================
function p.render(frame)
local args = frame:getParent() and frame:getParent().args or frame.args
local L = getLang(args)
local pageArgument = mw.uri.decode(trim(args.argument or ""))
local cheminRaw = trim(args.path or args.chemin or "")
local niveau = toNumber(args.level or args.niveau, 0) + 1
local typeArg = trim(args.type or "")
local avertissements = trim(args.warnings or args.avertissements or "")
local pageParam = trim(args.page or "")
local cheminParts = split(cheminRaw, "@@@")
local lastPath = safeIndex(cheminParts, #cheminParts, "")
local racineParts = split(lastPath, ":::")
local racine = safeIndex(racineParts, 2, "")
local pageDestination = smwAskOneTitle(frame, pageArgument)
local paramsRaw = smwShow(frame, pageArgument, msg(L, "prop_page_params"))
if paramsRaw == "" and L ~= "fr" then
paramsRaw = smwShow(frame, pageArgument, MESSAGES.fr.prop_page_params)
end
local params = split(paramsRaw, "<>")
if not params[1] or params[1] == "" then
return '<div class="aucun-contenu">' .. msg(L, "none_content") .. '</div>__NOTOC__'
end
local idArgument = safeIndex(params, 1, "")
local pairesJustifsRaw = safeIndex(params, 2, "")
local pairesObjRaw = safeIndex(params, 3, "")
local nbJustifs = toNumber(safeIndex(params, 4, "0"), 0)
local nbObjs = toNumber(safeIndex(params, 5, "0"), 0)
local pageDebatDetaille = safeIndex(params, 6, "")
local bandeauxJustifsCsv = safeIndex(params, 7, "")
local bandeauxObjsCsv = safeIndex(params, 8, "")
local contenuArgument = smwShow(frame, pageArgument, msg(L, "prop_argument_content"))
if (contenuArgument == "" or contenuArgument == nil) and L ~= "fr" then
contenuArgument = smwShow(frame, pageArgument, MESSAGES.fr.prop_argument_content)
end
local avertHtml = ""
if avertissements and avertissements ~= "" then
avertHtml = expandBandeaux(frame, avertissements, L)
end
local preOpen, preClose = "", ""
if niveau == 1 then
preOpen = string.format('<div class="contenu-argument-%s">', typeArg or "")
preClose = '</div>'
end
local bodyHtml = {}
table.insert(bodyHtml, string.format(
'<div class="contenu-argument">%s</div>',
contenuArgument or ""
))
if pageDebatDetaille and pageDebatDetaille ~= "" then
local carteProp = msg(L, "prop_arguments_map")
local carteArgs = smwShow(frame, pageDebatDetaille, carteProp)
if (carteArgs == "" or carteArgs == nil) and L ~= "fr" then
carteArgs = smwShow(frame, pageDebatDetaille, MESSAGES.fr.prop_arguments_map)
end
table.insert(bodyHtml, string.format([===[
<div class="carte-debat-detaille onglet-externe">
<div class="titre-debat-detaille">%s</div>
%s
</div>]===], msg(L, "detailed_debate_title", pageDebatDetaille), carteArgs or ""))
else
local function buildList(pairesRaw, count, sens, sensInverseOpt)
local out = {}
local paires = split(pairesRaw, "&&&")
local sensInverse = sensInverseOpt
for i = 1, count do
local paire = split(safeIndex(paires, i, ""), "-¡-")
local id = safeIndex(paire, 1, "")
local titre = safeIndex(paire, 2, id)
local titreEnc = urlencode(titre)
local idEnc = urlencode(id)
local t = sens
if sensInverse then
t = (typeArg == "pour") and "contre" or "pour"
end
table.insert(out, string.format([===[
<div class="argument-expandable">
<div id="%s" class="argument argument-expandable-title level-%d level-sup"
data-template="%s"
data-page="%s"
data-argument="%s"
data-type="%s"
data-level="%d"
data-root="%s"
data-path="%s@@@%s:::%s"
data-warnings="%s"
>[[File: Expand.svg | 13px | link= | alt= | class=fleche-deroulante]][[File: Argument-%s.svg | 17px | link= | alt= | class=pictogramme-h4 mw-no-invert]]<span>%s</span>
</div>
<div class="argument-content-wrapper"></div>
</div>]===],
anchorencode(titre),
niveau,
msg(L, "prop_argument_content"),
mw.text.nowiki(pageParam or ""),
idEnc,
mw.text.nowiki(t),
niveau,
mw.text.nowiki(racine),
mw.text.nowiki(cheminRaw or ""),
mw.text.nowiki(t),
titreEnc,
mw.text.nowiki(avertissements or ""),
mw.text.nowiki(t),
mw.text.nowiki(titre)
))
end
if #out == 0 then
if sensInverse then
return '<div class="aucun-argument">' .. msg(L, "none_objection") .. "</div>"
else
return '<div class="aucun-argument">' .. msg(L, "none_argument") .. "</div>"
end
end
return table.concat(out, "")
end
local formJust = msg(L, "form_justifications")
local formObj = msg(L, "form_objections")
local formNew = msg(L, "form_new_argument_title")
local formType = msg(L, "form_type")
if L ~= "fr" then
formJust = formJust ~= "" and formJust or MESSAGES.fr.form_justifications
formObj = formObj ~= "" and formObj or MESSAGES.fr.form_objections
formNew = formNew ~= "" and formNew or MESSAGES.fr.form_new_argument_title
formType = formType ~= "" and formType or MESSAGES.fr.form_type
end
local modJust = formlink(
frame,
formJust,
pageDestination,
msg(L, "edit"),
msg(L, "edit_justifs_tt")
)
local modObj = formlink(
frame,
formObj,
pageDestination,
msg(L, "edit"),
msg(L, "edit_objs_tt")
)
local typeJust = msg(L, "type_justification")
local typeObj = msg(L, "type_objection")
if L ~= "fr" then
typeJust = typeJust ~= "" and typeJust or MESSAGES.fr.type_justification
typeObj = typeObj ~= "" and typeObj or MESSAGES.fr.type_objection
end
local btnJust = queryformlink(
frame,
formNew,
string.format("%s[%s]=%s&%s[ID]=%s&_run",
formNew,
formType,
(typeJust or ""),
formNew,
(idArgument or "")
),
"post button",
msg(L, "add_argument"),
msg(L, "add_justif_tt", (pageArgument or ""))
)
local btnObj = queryformlink(
frame,
formNew,
string.format("%s[%s]=%s&%s[ID]=%s&_run",
formNew,
formType,
(typeObj or ""),
formNew,
(idArgument or "")
),
"post button",
msg(L, "add_objection"),
msg(L, "add_obj_tt", (pageArgument or ""))
)
local gauche = string.format([===[
<div class="colonne-gauche">
<div class="NavFramex %s">
<div class="NavHead"><span class="titre-boite">%s</span>
<span class="modifier-section">%s</span></div>
<div class="NavContent">
<div>%s</div>
%s
</div>
<div class="NavButton">
<div class="bouton-ajouter navigation-not-searchable">%s</div>
</div>
</div>
</div>]===],
(typeArg == "pour") and "bordure-argument-pour" or "bordure-argument-contre",
msg(L, "justifs_title"),
modJust,
expandBandeaux(frame, bandeauxJustifsCsv, L),
(pairesJustifsRaw ~= "" and buildList(pairesJustifsRaw, nbJustifs, typeArg, false) or '<div class = "aucun-argument">' .. msg(L, "none_argument") .. "</div>"),
btnJust
)
local droite = string.format([===[
<div class="colonne-droite">
<div class="NavFramex %s">
<div class="NavHead"><span class="titre-boite">%s</span>
<span class="modifier-section">%s</span></div>
<div class="NavContent">
<div>%s</div>
%s
</div>
<div class="NavButton">
<div class="bouton-ajouter navigation-not-searchable">%s</div>
</div>
</div>
</div>]===],
(typeArg == "pour") and "bordure-argument-contre" or "bordure-argument-pour",
msg(L, "objs_title"),
modObj,
expandBandeaux(frame, bandeauxObjsCsv, L),
(pairesObjRaw ~= "" and buildList(pairesObjRaw, nbObjs, typeArg, true) or '<div class="aucun-argument">' .. msg(L, "none_objection") .. "</div>"),
btnObj
)
table.insert(bodyHtml, '<div class="colonnes">')
table.insert(bodyHtml, gauche)
table.insert(bodyHtml, droite)
table.insert(bodyHtml, '</div>')
end
local html = {}
if avertHtml ~= "" then
table.insert(html, string.format('<div>%s</div>', avertHtml))
end
table.insert(html, preOpen)
table.insert(html, table.concat(bodyHtml, ""))
table.insert(html, preClose)
table.insert(html, "__NOTOC__")
return table.concat(html, "")
end
return p