Environnement de développement
L'attribut @env="dev" du fichier de configuration permet notamment d'afficher l'intégralité de la trace d'une erreur dans la page courante.
<configuration xmlns="http://certic.unicaen.fr/max/ns/1.0" env="dev" ... >
...
</configuration>
En phase de développement, il est conseillé d'installer le bundle max-dev :
climax bundles-add max-dev
Développement d'un bundle de vocabulaire
- Le dossier racine du bundle doit être placé (directement ou via un lien symbolique) dans le répertoire .max/basex/webapp/max/bundles :
ln -s /path/to/my_max_instance/.max/basex/webapp/max/bundles/my_bundle /path/to/my_bundle
- Le dossier racine du bundle doit contenir un fichier expath-pkg.xml décrivant le bundle :
<package xmlns="http://expath.org/ns/pkg"
name="name"
abbrev="abbrev_name"
version="0.0.1"
spec="1.0">
<!-- dépendances -->
<dependency package="max"/>
<!-- titre -->
<title>...</title>
<!-- url vers page du bundle -->
<home>...</home>
<xquery>
<!-- namespace du bundle -->
<namespace>...</namespace>
<!-- nom du fichier xqm contenant la fonction bundle-namespace:doc-to-html(), stocké dans le répertoire abbrev_name du bundle-->
<file>...</file>
</xquery>
</package>
Transformation d'un document
Un document source XML est accessible sur la route :
/{$lang=[a-z]{2}}/{$collection=.+}/{$doc=[a-zA-Z0-9_]+}.html
exemple : le document stocké dans macollection/fichier.xml sera accessible sur /fr/macollection/fichier.html
ou la route :
/{$lang=[a-z]{2}}/{$doc=[a-zA-Z0-9_]+}.html
exemple : le document stocké dans fichier.xml sera accessible sur /fr/fichier.html (si aucun fichier d'autoroute nommé fichier.xq n'existe).
Ajouter une fonctionnalité xquery
Autoroute
Créer dans le dossier du bundle un fichier autoroute/my_feature.xq. Le résultat de cette XQuery est automatiquement disponible sur la route :
/{$lang=[a-z]{2}}/my_feature.html. Un exemple (tdm.xq) est disponible dans le max-dumb-xml.
Cette XQuery reçoit le paramètre $lang issu de la route courante.
Fonctionnalité avancée
Ajouter une fonction RestXQ dans un fichier .xqm du bundle.
Templating
Les templates HTML doivent être placés dans le répertoire templates du bundle.
Le rendu d'un template se fait à l'aide de la fonction templating:render($template as xs:string, $parameters as map).
Les paramètres ($parameters) sont disponibles au sein du template.
Exemple :
<!-- example : my_bundle/templates/exemple.html-->
<html>
<head>
<title>{$title}</title>
</head>
<body>
<main>{$content}</main>
</body>
</html>
(: example : my_bundle/my_bundle/my_file.xqm :)
module namespace my-bundle = "...";
import module namespace templating = "https://certic.unicaen.fr/max/templating" at '../../../core/templating.xqm';
declare
%rest:GET
%rest:path("/my-bundle/render_example.html")
function my-bundle:render_example(){
let $content := <h1>Exemple</h1>
let $title := "Mon titre"
return templating:render("exemple.html"), map{'content' : $content, 'title': $title})
};
Héritage
La racine du template fils doit être déclarée à l'aide de la balise <template/> et de l'attribut data-extends:
<!-- template_fils.html -->
<template data-extends="template_de_base.html">
[...]
</template>
Blocs nommés
Il est possible de nommer des blocs à l'aide de la balise <slot/> et de l'attribut name :
<!-- template_de_base.html -->
<slot name="mon_bloc"></slot>
Pour ensuite en définir leur contenu dans un template fils. La définition du bloc se fait avec la balise HTML souhaitée et l'attribut slot correspondant au nom du bloc parent (@name) à redéfinir :
<!-- template_fils.html -->
<div slot="mon_bloc">
Bonsoir
</div>
Inclusions
L'inclusion d'un template au sein d'un autre se fait à l'aide de la balise <template/> et de l'attribut data-include
<!-- template.html -->
<template data-include="autre_template.html"></template>
Injection de variables
L'ensemble des variables passées en paramètre de l'appel à la fonction render peuvent être injectées dans un template :
<p>{$ma_variable}</p>
Appels de fonction
L'ensemble des fonctions des modules déclarés dans le fichier expath-pkg.xml de MaX sont accesibles depuis les templates.
<!-- ajout du titre du corpus numérique dans la balise <title/>-->
<head><title>{conf:get-title()}</title></head>
[...]
<!-- traduction de la clé 'tdm' -->
<span><title>{i18n:translate('tdm', $lang)}</span>
Internationalisation
Les fichiers de traductions doivent être placées dans le dossier locales du bundle, avec un fichier au format json par langue.
{
"gm": "bonjour",
"ge": "bonsoir"
}
La traduction se fait à l'aide de la fonction i18n:translate($key, $lang) :
<p>{i18n:translate('ge', $lang)}</p>
Note : La variable $lang peut être passée en paramètre de l'appel à la fonction render.
Développement d'un bundle "générique"
Ajouter une route RestXQ
Créer un fichier [my_bundle].xqm dans le dossier du bundle, celui-ci sera automatiquement chargé par MaX.
Templating
Le système d'héritage et de blocs nommés n'est disponible que pour les bundle de vocabulaire. Il est cependant possible d'effectuer un rendu via un template avec la fonction :
templating:eval-template($doc as document, options as map*)
<!--template my_bundle/templates/index.html-->
<html>
<head></head>
<body>
<h1>Poids des sources XML</h1>
<ul>
{
for $source in $sources
return <li>{$source/data()} : {string($source/@size)}</li>
}
</ul>
</body>
</html>
(:template my_bundle/my_bundle.xqm:)
[...]
declare
%rest:GET
%output:method("html")
%output:html-version("5.0")
%output:encoding("UTF-8")
%rest:path("/bundles/my-bundle/example.html")
function my-bundle:index(){
let $sources := db:list-details($database:max-db)
let $templateDoc := doc('./templates/index.html')
let $collections := max-db:max-collections()
return templating:eval-template(
$templateDoc,
map{'sources': $sources})
};
Hook "post-render"
Après avoir effectué le rendu via le sytème de templating, MaX applique les éventuelles fonctions xquery post-render.xq des différents bundles actifs.
Ces fonctions peuvent alors modifier l'arbre HTML rendu par le système de templating (via le paramètre nommé $html).
(:fichier extrait du bundle max-dev (max-dev/post-render.xqm) : ajoute un bouton vers la page d'index du bundle :)
xquery version "3.0";
import module namespace conf = 'https://certic.unicaen.fr/max/conf' at '../../core/conf.xqm';
declare variable $html external;
if(conf:is-dev-mode())
then
let $devLink :=<a
style="position: fixed; bottom :5px; left: 5px; background-color: #333; padding: 2px 5px; color: white" href="/bundles/max-dev/index.html">?</a>
return
copy $c := $html
modify (
insert node $devLink into $c//*:body
)
return $c
else $html