« Module:Header template » : différence entre les versions
Usage conforme à d:Wikidata:WikiProject Books/Microdata |
nettoyage du lien quand utilisé comme label |
||
Ligne 76 : | Ligne 76 : | ||
end ) |
end ) |
||
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)%]%]', function( page ) |
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)%]%]', function( page ) |
||
return formatLink( page, page, schema_property ) |
return formatLink( page, mw.ustring.gsub( page, '%.*/', '') , schema_property ) |
||
end ) |
end ) |
||
return wikitext |
return wikitext |
Version du 26 décembre 2017 à 17:01
- Voir Aide:Transclusion pour l’utilisation de la commande <pages index=… />.
- Modèle utilisé par la balise <pages/> pour générer les boîtes titres
- Les paramètres acceptés par ce modèle proviennent de la page d’index.
- Les paramètres peuvent aussi être passés à la commande "pages".
- Exemple :
<pages index=foo header=1 auteur="[[Balzac]]" />
- Détails techniques
Ce modèle est implémenté en Lua via le module Header Template. Il utilise les paramètres suivants définis par l’extension ProofreadPage :
paramètre | description |
---|---|
from | la valeur from définie par l’utilisateur, 1 par défaut |
displayed_from | le numéro de page à afficher pour la première page (par défaut celui défini dans la page Livre:) |
to | la valeur to définie par l’utilisateur, par défaut la dernière page |
displayed_to | le numéro de page à afficher pour la dernière page (par défaut celui défini dans la page Livre:) |
current | le nom du lien pointant vers la page courante dans le sommaire de la page d’index du Livre |
prev | le nom du lien pointant vers la page précédant la page courante dans le sommaire de la page d’index du Livre |
next | le nom du lien pointant vers la page suivant la page courante dans le sommaire de la page d’index du Livre |
value | la valeur de l’attribut header de la balise <pages />, ou toc si ni from ni to ne sont précisés |
Les autres paramètres sont les noms des champs apparaissant dans le formulaire de l’index du Livre. Leur valeur est celle qui apparaît dans le formulaire, sauf si l’utilisateur l'a redéfinie dans la balise <pages />, auquel cas, la valeur de la balise a priorité sur celle de l’index.
Pour le paramètre type, la valeur apparaissant dans le menu déroulant du formulaire de la page d’index est convertie en un nom à usage interne suivant le tableau de correspondance suivant :
valeur interne | valeur du menu déroulant |
---|---|
book | Livre |
collection | Recueil |
journal | Journal ou revue |
phdthesis | Thèse, rapport |
dictionary | Dictionnaire, encyclopédie, ouvrage de référence |
C’est la valeur interne qui est utilisée par le modèle. De même, si l’utilisateur souhaite redéfinir la valeur du champ type à l’intérieur de la balise <pages />, il doit utiliser la valeur interne.
function cleanCoinsParameter( param )
param = string.gsub( param, "%[%[.*|(.*)%]%]", "%1" )
return string.gsub( param, "%[%[(.*)%]%]", "%1" )
end
function formatString( str, schema_property )
return tostring(mw.html.create('span')
:attr('itemprop', schema_property)
:wikitext(str)
)
end
function formatYear( date, schema_property )
year = tonumber( date )
if year == nil or year < 1000 then
return tostring(mw.html.create('span')
:attr('itemprop', schema_property)
:wikitext(date))
else
return tostring(mw.html.create('time')
:attr('datetime', year)
:attr('itemprop', schema_property)
:wikitext(date))
end
end
function formatPublisherWithName( name )
return tostring(mw.html.create('span')
:attr('itemprop', 'publisher')
:attr('itemscope', '')
--TODO: guess type ? :attr('itemtype', 'http://schema.org/Organization')
:tag('span')
:attr('itemprop', 'name')
:wikitext(name)
:done()
)
end
function formatLink( page, label, schema_property)
-- TODO: itemid quand on pourra répérer les ids Wikidata https://phabricator.wikimedia.org/T152909
local title = mw.title.new( page )
if title == nil then
return tostring(mw.html.create('span')
:attr('itemprop', schema_property)
:attr('itemscope', '')
--TODO: type :attr('itemtype', 'http://schema.org/Person')
:wikitext('[[' .. page .. '|<span itemprop="name">' .. label .. '</span>]]')
)
end
if title.isRedirect then
title = title.redirectTarget
end
local tag = mw.html.create('span')
:attr('itemprop', schema_property)
:attr('itemscope', '')
--TODO: type :attr('itemtype', 'http://schema.org/Person')
:wikitext('[[' .. title.fullText .. '|<span itemprop="name">' .. label .. '</span>]]')
:tag('link')
:attr('itemprop', 'mainEntityOfPage')
:attr('href', title:fullUrl(nil, 'canonical'))
:done()
itemId = mw.wikibase.getEntityIdForTitle(title.fullText)
if itemId ~= nil then
tag:attr('itemid', 'http://www.wikidata.org/entity/' .. itemId)
end
return tostring(tag)
end
function parseLinkWikitext( wikitext, schema_property )
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)|(.*)%]%]', function( page, link )
return formatLink( page, link, schema_property )
end )
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)%]%]', function( page )
return formatLink( page, mw.ustring.gsub( page, '%.*/', '') , schema_property )
end )
return wikitext
end
function formatTitleLink( page, label, schema_property )
local title = mw.title.new( page )
if title == nil then
return '[[' .. page .. '|' .. label .. ']]'
end
if title.isRedirect then
title = title.redirectTarget
end
tag = mw.html.create('span')
:attr('itemprop', schema_property)
:attr('itemscope', '')
:attr('itemtype', 'http://schema.org/CreativeWork') --TODO: find a more relenvant type
:wikitext('[[' .. title.fullText .. '|<span itemprop="name">' .. label .. '</span>]]')
:tag('link')
:attr('itemprop', 'mainEntityOfPage')
:attr('href', title:fullUrl(nil, 'canonical'))
:done()
itemId = mw.wikibase.getEntityIdForTitle(title.fullText)
if itemId ~= nil then
tag:attr('itemid', 'http://www.wikidata.org/entity/' .. itemId)
end
return tostring(tag)
end
function parseTitleWikitext( wikitext, schema_property )
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)|(.*)%]%]', function( page, link )
return formatTitleLink( page, link, schema_property )
end )
wikitext = mw.ustring.gsub( wikitext, '%[%[([^|]*)%]%]', function( page )
return formatTitleLink( page, page, schema_property )
end )
return wikitext
end
function headerTemplate( frame )
local parentFrame = frame:getParent()
local args = parentFrame.args
local page = mw.title.getCurrentTitle()
local item = mw.wikibase.getEntity()
local headerType = args.value
if args.header_type and args.header_type ~= '' then
headerType = args.header_type
end
headerType = mw.ustring.lower( headerType ) --Permet d'écrire le type en majuscule ou en minuscule
local estSommaire = (headerType == 'sommaire' or headerType == 'toc')
--Custom page numbers
local from = ''
if args.displayed_from and args.displayed_from ~= '' then
from = args.displayed_from
elseif args.from then
from = args.from
end
local to = ''
if args.displayed_to and args.displayed_to ~= '' then
to = args.displayed_to
elseif args.to then
to = args.to
end
local schema_type = 'http://schema.org/CreativeWork'
if args.type then
if args.type == 'book' then
if estSommaire then
schema_type = 'http://schema.org/Book'
else
schema_type = 'http://schema.org/Chapter'
end
elseif args.type == 'collection' then
if estSommaire then
schema_type = 'https://schema.org/Collection'
end
elseif args.type == 'journal' then
if estSommaire then
schema_type = 'https://schema.org/PublicationVolume'
else
schema_type = 'http://schema.org/Article'
end
elseif args.type == 'phdthesis' then
if estSommaire then
schema_type = 'http://schema.org/Thesis'
else
schema_type = 'http://schema.org/Chapter'
end
end
end
--Début du header
local html = mw.html.create()
local container = html:tag('div')
:attr('itemscope', '')
:attr('itemtype', schema_type)
if item ~= nil then
container:attr('itemid', 'http://www.wikidata.org/entity/' .. item.id)
end
classement( parentFrame, page, args )
if args.header_type == 'empty' then
if args.sommaire then
container:tag( 'div' )
:addClass('ws-summary')
:css('margin-top', '1em')
:newline()
:wikitext(args.sommaire)
end
return html
end
local headertemplate = container:tag('div')
:attr('id', 'headertemplate')
:addClass('ws-noexport')
:tag('div')
if args.type == 'journal' then
headertemplate:addClass('headertemplate-journal')
else
headertemplate:addClass('headertemplate')
end
--Auteur
if args.auteur and args.auteur ~= '' then
headertemplate:tag('div')
:addClass('headertemplate-author')
:wikitext(parseLinkWikitext(args.auteur, 'author'))
end
--Titre
local titre = formatString( page.baseText, 'name' )
if args.type == 'collection' then
if args.recueil and args.recueil ~= '' then
-- Commenté pour tester avec uniquement le nom du recueil, le titre lui est déjà
-- dans le navigateur et fréquemment en début de la page.
-- titre = titre .. ' — <i>' .. args.recueil .. '</i>'
titre = '<i>' .. parseTitleWikitext(args.recueil, 'isPartOf') .. '</i>'
elseif args.current then
titre = formatString( args.current, 'name' )
else
if estSommaire then
titre = formatString( titre, 'name' )
else
titre = parseTitleWikitext(titre, 'isPartOf')
end
end
if args.publication and args.publication ~= '' then
titre = titre .. ' <span style="font-size:90%;">(' .. args.publication .. ')</span>'
end
elseif args.type == 'journal' then
if estSommaire then
titre = formatString( args.titre, 'name' )
elseif args.current then
titre = formatString( args.current, 'name' )
else
titre = parseTitleWikitext(titre, 'isPartOf')
end
else
if args.titre then
titre = args.titre
end
if estSommaire then
titre = formatString( titre, 'name' )
else
titre = parseTitleWikitext(titre, 'isPartOf')
end
if args.publication and args.publication ~= '' then
titre = titre .. ' <span style="font-size:90%;">(' .. args.publication .. ')</span>'
end
end
if estSommaire and args['sous_titre'] and args['sous_titre'] ~= '' then
titre = titre .. ' <br/><small>' .. args['sous_titre'] .. '</small>'
end
headertemplate:tag('div')
:addClass('headertemplate-title')
:wikitext(titre)
--References
local references = headertemplate:tag('div')
:addClass('headertemplate-reference')
if args.traducteur and args.traducteur ~= '' then
references:wikitext('Traduction par ' .. parseLinkWikitext(args.traducteur, 'translator') .. '.')
:tag('br')
end
if estSommaire and args.illustrateur and args.illustrateur ~= '' then
references:wikitext('Illustrations par ' .. parseLinkWikitext(args.illustrateur, 'illustrator') .. '.')
:tag('br')
end
if estSommaire and args.volume and args.volume ~= '' then
references:wikitext( formatString( args.volume, 'volumeNumber' ) )
:tag('br')
end
local infos = {} --Liste des données à afficher séparés par une virgule
if args.type == 'collection' then
if args.titre and args.titre ~= '' then
table.insert( infos, '<i>' .. args.titre .. '</i>' )
end
if args.editeur_scientifique and args.editeur_scientifique ~= '' then
table.insert( infos, 'Texte établi par ' .. parseLinkWikitext( args.editeur_scientifique, 'editor' ) )
end
if args.editeur and args.editeur ~= '' then
table.insert( infos, formatPublisherWithName( args.editeur ) )
end
if args.annee and args.annee ~= '' then
table.insert( infos, formatYear( args.annee, 'datePublished' ) )
end
if not estSommaire then
if args.volume and args.volume ~= '' then
table.insert( infos, formatString( args.volume, 'volumeNumber' ) )
end
end
elseif args.type == 'journal' then
if not estSommaire then
table.insert( infos, '<i>' .. args.titre .. '</i>' )
if args.volume and args.volume ~= '' then
table.insert( infos, formatString( args.volume, 'volumeNumber' ) )
end
end
if args.annee and args.annee ~= '' then
table.insert( infos, formatYear( args.annee, 'datePublished' ) )
end
else
if args.editeur_scientifique and args.editeur_scientifique ~= '' then
table.insert( infos, 'Texte établi par ' .. parseLinkWikitext( args.editeur_scientifique, 'editor' ) )
end
if args.editeur and args.editeur ~= '' then
table.insert( infos, formatPublisherWithName( args.editeur ) )
end
if args.annee and args.annee ~= '' then
table.insert( infos, formatYear( args.annee, 'datePublished' ) )
end
end
local line = ''
if infos ~= {} then
line = table.concat( infos, ', ' )
end
--Parenthèse
if not estSommaire and from ~= '' then
local temp = ''
if args.volume and args.volume ~= '' and args.type ~= 'collection' and args.type ~= 'journal' then
temp = formatString( args.volume, 'volumeNumber' ) .. ', '
end
if from ~= to or from ~= '-' then
temp = temp .. pagination( from, to )
end
if temp ~= '' then
line = line .. ' (' .. temp .. ')'
end
end
if line ~= '' then
references:wikitext(line .. '.')
end
local subheader = container:tag('div')
:attr('id', 'subheader')
:addClass('ws-noexport')
:css('margin-bottom', '1.5em')
if estSommaire then
local texteEntier = mw.title.new( page.prefixedText .. '/Texte entier' )
if texteEntier and texteEntier.exists then
subheader:tag('div')
:css('text-align', 'center')
:wikitext('[[' .. texteEntier.fullText .. '|Texte sur une seule page]]')
end
end
if (not estSommaire or (args.header_type and args.header_type =='toc')) and ((args.prev and args.prev ~= '') or (args.next and args.next ~= '')) then
local maxwidth = 50
if args.current and args.current ~= '' then
maxwidth = 33
end
local footer = subheader:tag('div')
:addClass('footertemplate')
:addClass('ws-noexport')
local nav = footer:tag('div')
:css('width', '100%')
:css('padding-left', '0px')
:css('padding-right', '0px')
:css('background-color', 'transparent')
if args.prev and args.prev ~= '' then
nav:tag('div')
:css('text-align', 'left')
:css('float', 'left')
:css('max-width', maxwidth .. '%')
:tag('span')
:attr('id', 'headerprevious')
:tag('span')
:css('color', '#808080')
:wikitext('◄ ')
:done()
:wikitext(parseLinkWikitext(args.prev, 'previousItem'))
end
if args.next and args.next ~= '' then
nav:tag('div')
:css('text-align', 'right')
:css('float', 'right')
:css('max-width', maxwidth .. '%')
:tag('span')
:attr('id', 'headernext')
:wikitext(parseLinkWikitext(args.next, 'nextItem'))
:tag('span')
:css('color', '#808080')
:wikitext(' ►')
end
if type ~= 'collection' and args.current and args.current ~= '' then
nav:tag('div')
:attr('itemprop', 'name')
:css('text-align', 'center')
:css('margin-left', '25%')
:css('margin-right', '25%')
:wikitext(args.current)
end
footer:tag('div')
:css('clear', 'both')
end
-- Inclusion de l'épigraphe et du sommaire
if headerType == 'toc' then
if args.epigraphe and args.epigraphe ~= '' then
container:wikitext(args.epigraphe)
:newline()
end
container:tag('div')
:addClass('ws-summary')
:css('margin-top', '1em')
:wikitext(args.sommaire)
elseif headerType == 'sommaire' then
html:wikitext('<div id="ws-summary">') --Bad hack, outputs unbalanced HTML
end
--Métadonnées schema.org supplémentaires
container:tag('link')
:attr('itemprop', 'mainEntityOfPage')
:attr('href', page:fullUrl(nil, 'canonical'))
container:tag('meta')
:attr('itemprop', 'inLanguage')
:attr('content', 'fr') --TODO: que faire pour l'ancien français...
if args.lieu and args.lieu ~= '' then
container:tag('meta')
:attr('itemprop', 'http://purl.org/library/placeOfPublication')
:attr('content', args.lieu) --TODO: is it the best property URI and the best value format?
end
-- Métadonnées, see http://ocoins.info/ for coins.
local coins = {}
local uriCoins = 'ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3A'
coins['rft.genre'] = 'unknown'
coins['rfr_id'] = tostring( page:fullUrl( nil, "canonical" ) )
local datahtml = container:tag('div')
:attr('id', 'ws-data')
:addClass('ws-noexport')
:css('display', 'none')
:css('speak', 'none')
if args.type then
datahtml:node( outputMicroformatRow( 'type', args.type ) )
end
if args.type and args.type == 'journal' then
uriCoins = uriCoins .. 'journal'
if estSommaire then
coins['rft.genre'] = 'publication'
coins['rft.jtitle'] = cleanCoinsParameter( titre )
else
coins['rft.genre'] = 'article'
coins['rft.atitle'] = cleanCoinsParameter( titre )
if args.titre then
coins['rft.jtitle'] = cleanCoinsParameter( args.titre )
datahtml:node( outputMicroformatRow( 'periodical', cleanCoinsParameter( args.titre ) ) )
end
end
else
uriCoins = uriCoins .. 'book'
if estSommaire then
coins['rft.btitle'] = cleanCoinsParameter( titre )
else
coins['rft.atitle'] = cleanCoinsParameter( titre )
end
if args.type and args.type == 'book' then
if estSommaire then
coins['rft.genre'] = 'book'
else
coins['rft.genre'] = 'bookitem'
end
end
end
datahtml:node( outputMicroformatRow( 'title', titre ) )
if args.auteur and args.auteur ~= '' then
datahtml:node( outputMicroformatRow( 'author', args.auteur ) )
coins['rft.au'] = cleanCoinsParameter( args.auteur )
end
if args.traducteur and args.traducteur ~= '' then
datahtml:node( outputMicroformatRow( 'translator', args.traducteur ) )
end
if args.illustrateur and args.illustrateur ~= '' then
datahtml:node( outputMicroformatRow( 'illustrator', args.illustrateur ) )
end
if args.school and args.school ~= '' then
datahtml:node( outputMicroformatRow( 'school', args.school ) )
end
if args.editeur and args.editeur ~= '' then
datahtml:node( outputMicroformatRow( 'publisher', args.editeur ) )
coins['rft.pub'] = cleanCoinsParameter( args.editeur )
end
if args.annee and args.annee ~= '' then
datahtml:node( outputMicroformatRow( 'year', args.annee ) )
coins['rft.date'] = args.annee
end
if args.lieu and args.lieu ~= '' then
datahtml:node( outputMicroformatRow( 'place', args.lieu ) )
coins['rft.place'] = args.lieu
end
if args.avancement and args.avancement ~= '' then
datahtml:node( outputMicroformatRow( 'progress', args.avancement ) )
end
if args.volume and args.volume ~= '' then
datahtml:node( outputMicroformatRow( 'volume', args.volume ) )
end
if args.current and args.current ~= '' then
datahtml:node( outputMicroformatRow( 'chapter', args.current ) )
end
if args.index then
datahtml:node( outputMicroformatRow( 'scan', args.index ) )
if args.image and mw.ustring.match(args.image, '^%d+$') ~= nil then
datahtml:node( outputMicroformatRow( 'cover', args.index .. '/' .. args.image ) )
end
end
if from ~= '' and to ~= '' then
if from == to then
datahtml:node( outputMicroformatRow( 'pages', from ) )
else
datahtml:node( outputMicroformatRow( 'pages', from .. '-' .. to ) )
end
coins['rft.spage'] = from
coins['rft.epage'] = to
end
datahtml:tag('span')
:addClass('Z3988')
:attr('title', uriCoins .. '&' .. mw.uri.buildQueryString( coins ))
:wikitext(' ')
return html
end
function classement( frame, page, args )
local classement = require 'Module:Classement'
local key = ''
if args.type and args.type == 'journal' then
key = classement.getSortKey( {args= {page.text}} )
elseif args.type and (args.type == 'dictionary' or args.type == 'collection') then
key = classement.getSortKey( {args= {page.subpageText}} )
elseif not page.isSubpage then
key = classement.getSortKey( {args= {page.text}} )
end
if key ~= '' then
--Evite le parse des paramètres passés à la page.
local child = frame:newChild{ title = page.text, args = {} }
child:preprocess( '{{DEFAULTSORT:' .. key .. '}}\n' )
end
end
function pagination( from, to )
if from ~= '' and to ~= '' then
if from == to then
return '<abbr title="page">p.</abbr> ' .. formatString( from, 'pagination' )
else
return '<abbr title="pages">pp.</abbr> ' .. formatString( from, 'pageStart' ) .. '-' .. formatString( to, 'pageEnd' )
end
end
end
function outputMicroformatRow( name, value )
return mw.html.create('span')
:addClass('ws-' .. name)
:wikitext(value)
end
local p = {}
function p.headerTemplate( frame )
return headerTemplate( frame )
end
return p