Le but de l'exercice est la génération d'un catalogue sur InDesign à partir d'une collection de fichiers XML.

1. Prérequis

  1. Une collection de fichiers XML qui sont valides par rapport au modèle de cours : baechli_product.xsd et baechli_product_typeDefinition.xsd
  2. Une installation fonctionnelle de la dernière version de eXistDB
  3. Une installation fonctionnelle de InDesign CS6 ou plus récent.

2. Une première requête XQuery

Connectez-vous à existDB. Pour ça, il faut d'abord lancer existDB. Ensuite on peut soit utiliser l'outil Java Admin Client proposé dans le menu contextuel de existDB, soit se connecter à la base de données eXist via WebDAV avec l'adresse http://localhost:8080/exist/webdav/db/. Le nom d'utilisateur par défaut est admin, le mot de passe par défaut est laissé vide.

Vous pouvez ensuite créer un dossier sur le serveur qui contiendra vos données XML. Le dossier peut être n'importe où sur le serveur. J'ai choisi de les mettre dans un dossier qui s'appelle baechli. Téléchergez ensuite votre collection de fichiers XML dans ce dossier et vérifiez que vous pouvez accèder aux fichiers via l'interface REST de eXistDB.

Pour créer un premier fichier XQuery, nous allons utiliser l'éditeur proposé par eXistDB qui s'appelle eXide. Naviguez sur http://localhost:8080/exist/apps/eXide/. Créez là un nouveau fichier XQuery avec le contenu suivant :

xquery version "3.0";

let $list := (1,2,3)
return
    <result>
        { for $num in $list
            return <num>{$num}</num>
        }
    </result>

Suite à la sauvegarde, vous pouvez cliquer sur Run et vérifier que votre première requête XQuery fonctionne.

3. Chercher les produits dans la base des données

Pour retrouver les produits dans votre base de données, vous pouvez utiliser la fonction collection de eXistDB :

xquery version "3.0";

declare option exist:serialize "method=xml media-type=text/xml"; 

let $products := collection("/db/CGDDS/cc2155/baechli_products")/product
return
    <products>
        { for $product in $products
        return $product
        }
    </products>

Quelques commentaires sur le code ci-dessus :

  1. Vérifiez que vous définissez le namespace que vous avez utilisé dans vos fichiers XML de produit. Très souvent, quand la requête XQuery est valide et ça devrait fonctionner, c'est qu'on a oublié le namespace.

  2. L'option serialize fait que eXist formate le résultat de la bonne manière et que touts les bons HEADERs sont envoyés au navigateur. Voici la documentation de tous paramètres de cette option.

  3. Pour trouver les fichiers XML dans un dossier, son chemin doit être donné comme paramètre à la fonction collection. Notez qu'il n'y a pas toute l'URL mais seulement le chemin à partir de la racine db.

  4. Sur cette collection, nous faisons toute de suite une requête XPath pour récupérer que les produits. Ceci garanti que nous n'avons pas autre chose dans notre variable $products comme par exemple un ficher XML qui n'est pas un produit ou même un ficher CSS ou autre.

Vérifiez que votre code affiche bien un fichier XML avec tous vos produits.

4. Préparer un template sur InDesign

Nous sommes donc prêts du côté eXistDB. De l'autre côté, nous devons préparer un fichier InDesign qui contient le layout et tous les styles de paragraphe et de caractère dont nous avons besoin.

Préparez pour ceci un fichier InDesign qui représente la présentation finale souhaitée pour catalogue. Pour le moment vous pouvez copier du contenu directement dans InDesign. Le contenu va être régénéré dynamiquement plus tard.

Quelques consignes :

  1. Utilisez un flux de texte unique qui contiendra tous les produits par chapitre. Ceci vous permettra de générer un ficher par chapitre.
  2. Quand vous formatez, essayez de faire un maximum avec les styles de caractère et de paragraphe. C'est plus gérable que du formatage via le XML généré.

Voici un exemple basique d'un template : Baechli.idml

5. Séparer le contenu du layout

Quand vous êtes contents de votre layout, vous pouvez séparer le contenu et le layout. Pour faire ceci, vous pouvez utiliser une fonction qui est prévue pour travailler avec l'outil InCopy. Après un clic droit sur le flux de texte qui représente votre contenu, vous choisissez l'option « exporter la séléction… » sous le point «InCopy».

Screenshot de l'option d'export en InDesign
Screenshot de l'export sur la version allemande d'InDesign
Le texte lié dans la palette de InDesign
Lien sur le texte

Cet export produira un fichier avec une extension icml. Ce fichier est connecté à InDesign via un lien. C'est le même principe comme avec les images. Le fichier est aussi visible est gérable dans la palette «Liens» de InDesign. Cette palette va être utilisée pour mettre à jour le document avec le contenu généré.

6. Inspecter et comprendre le fichier ICML

Le fichier ICML est du pur XML. En l'ouvrant avec un éditeur de texte, vous voyez votre contenu, le formatage, les définitions des styles et plein d'autres choses. En première vue, ceci peut sembler intimidant et complexe. Mais finalement, vous utiliseriez qu’une petite partie de toutes les fonctionnalités à disposition et vous pouvez ignorer ou même supprimer tout le reste.

Pour commencer à comprendre la structure du fichier, essayez de retrouver votre contenu. Le contenu est entouré par des balises Content, CharacterStyleRange et ParagraphStyleRange. Ils définissent les différents styles assignés au contenu :

<ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/name">
    <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
        <Content>Atom LT Hoody</Content>
    </CharacterStyleRange>
    <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/brand">
        <Content>Arc'Teryx</Content>
        <Br/>
    </CharacterStyleRange>
</ParagraphStyleRange>

Changez un style ou le contenu dans le XML. Après une sauvegarde, vous pouvez mettre à jour le lien sur InDesign et vous voyez l'effet de votre changement. Expérimentez avec fichier pour comprendre comment il fonctionne.

La possibilité de directement voir l'effet de vos changements vous permet aussi de réduire les métadonnées fortement. C'est plus pratique quand vous générez le XML automatiquement.

Quand vous ne savez pas comment faire quelque chose dans ICML (placer une image par exemple), faites-le dans InDesign et consultez le XML que ceci génère. Comme les métadonnées, vous pouvez très souvent enlever beaucoup de choses qui sont plus ou moins de valeurs par défaut.

Pour mieux comprendre le fonctionnement d'une balise, vous pouvez aussi consulter la documentation d’Adobe.

7. Générer un ICML pour vos produits

Pour reproduire votre fichier ICML avec XQuery, copiez dans un premier temps le XML de votre exemple dans le return de votre requête comme ci :

declare option exist:serialize "method=xml omit-xml-declaration=no process-xsl-pi=no encoding=UTF-8 standalone=yes"; 

...
let $products := collection("/db/CGDDS/cc2155/baechli_products")/product
return
    document {
        <?aid style="50" type="snippet" readerVersion="6.0" featureSet="257" product="10.0(70)" ?>,
        <?aid SnippetType="InCopyInterchange"?>,
        <Document DOMVersion="10.0" Self="d">
            ...
        </Document>
    }

Soyez attentif à l'inclusion des Processing Instructions. InDesign s'attend à un attribut standalone=yes. Ceci figure dans la XML declaration qui est définie dans l'option serialize.

Vous devez également ajouter deux autres Processing instructions aid. Ceci fait que vous devez utlisier la fonction document de XQuery pour produire une série de balises (séparé par des commas) au lieu d'une seule balise root. Cliquez sur Run dans l'éditeur eXide pour visualiser le XML résultant.

Dès que vous arrivez à reproduire le code de votre fichier .icml depuis XQuery, vous pouvez commencer à générer du contenu.
Mettez pour ceci les parties qui contiennent les informations d'un produit dans une boucle for qui traverse tous les produits de votre base de données. Pour chacun des produits, remplacez les données en dur avec la bonne reqûete XPath.

...

let $products := collection("/db/CGDDS/cc2155/baechli_products")/product
return
    ....
    <Document>
        ...
        <Story>
        ...
	        { for $product in $products
	          return  <ParagraphStyleRange AppliedParagraphStyle="ParagraphStyle/name">
	                <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/$ID/[No character style]">
	                    <Content>{$product//name}</Content>
	                </CharacterStyleRange>
	                <CharacterStyleRange AppliedCharacterStyle="CharacterStyle/brand">
	                    <Content>{$product//brand}</Content>
	                    <Br/>
	                </CharacterStyleRange>
	            </ParagraphStyleRange>
	        }
      	</Story>
    </Document>
    }

Copiez le résultat et remplacez le contenu de votre fichier icml avec le code généré. Vous pouvez ensuite tester si tout est s'est bien passé en visualisant le résultat sur InDesign. Si ça fonctionne, je vous félicite. Vous avez généré un catalogue de produit sur InDesign. Voici le fichier XQuery complèt avec métadonnées et toutes les informations omises en haut.

8. Autmomatiser le processus

Pour éviter de devoir faire du copier-coller, vous pouvez utiliser l'outil curl. Curl est une librairie qui permet de télécharger des fichiers via la ligne de commande. Vous pouvez l'utiliser pour télécharger le résultat de votre requête XQuery directement au bon endroit avec le bon nom. Par exemple :

curl http://localhost:8080/exist/rest/db/baechli/InDesign.xql -o ~/Desktop/baechli.icml

Cette commande sauvegarde le résultat de ma requête XQuery dans InDesign.xql sur mon Desktop avec le bon nom et la bonne extension. L'option -o signifie simplement que le chemin qui suit définit le fichier résultant. Des outils comme Automator sur Mac ou Batch sur Windows vous permettent même de créer des programmes cliquables qui font ce téléchargement.