Des sites web Node.js pour débuter en JavaScript serveur avec NodeAtlas

Je vous propose de créer vos propres sites Node.js armés pour un rendu de qualité côté client et avec très peu de JavaScript. Vous pourrez ensuite, petit à petit et à votre rythme, vous plonger dans la partie Back-end JavaScript offerte par Node.js. Tout ceci est possible grâce au module npm (node.js package manager) NodeAtlas.

NodeAtlas est un Framework JavaScript côté serveur orienté Front-end, c'est-à-dire qu'il permet de faire tourner des sites multilingues complets uniquement avec les parties Vue et Route d'activées le reste étant fait par le framework. Bien évidemment, en activant la partie Contrôleur et Modèle vous prendrez la main sur le JavaScript serveur et vous pourrez créer de grands sites de qualités avec tout ce que l'on est en droit d'attendre : compte utilisateur, envoi de message, chat en direct... ou de solides applications web couplées à des Frameworks Javascript Frontaux comme Vue ou même simplement du code maison ! Mais commençons par le commencement.

Sachez que le blog sur lequel vous lisez cet article est fait avec NodeAtlas (obtenir les sources), ce qui lui permet de respecter facilement les standards HTML/CSS et de fournir sans efforts de hautes performances.

NodeAtlas est designé pour :

Créer un projet et lancer son Hello World

Il existe bien des manières d'utiliser le module NodeAtlas. Nous allons ici l'utiliser avec le require de Node.js.

Installer le module NodeAtlas

Nous allons prendre en considération que vous avez déjà installé Node.js et npm sur votre machine.

  1. Créez vous n'importe où sur votre machine l'arborescences suivante :

    project-directory/
    └─ server.js
    
  2. et remplissez le contenu de server.js avec le code suivant :

    require('node-atlas')().run({
     browse: true
    });
    

    Note: browse ouvrira votre navigateur.

  3. puis placez-vous ensuite dans votre répertoire project-directory et ouvrez un invité de commande (sous Windows, dans l'explorer de dossier, maintenez la touche shift enfoncée et faites un clique droit ; sélectionnez ensuite l'option « Ouvrir une fenêtre de commandes ici »).

  4. Entrez la commande npm install node-atlas pour installer le module NodeAtlas localement, dans votre dossier projet. Une fois installé, votre contenu de répertoire projet devrait ressembler à ceci :

    project-directory/
    ├─ node_modules/
    │  ├─ node-atlas/
    │  ┊┉
    │
    └─ server.js
    
  5. Enfin, testez le tout en tapant dans votre console node server.js --lang fr-fr pour obtenir le message « NodeAtlas est maintenant en français ! » suivit de « NodeAtlas c'est lancé en mode « Simple Serveur Web » car aucun « project-directory\webconfig.json » n'a été trouvé. » ou de « NodeAtlas c'est arrêté car le port 80 est déjà écouté par une autre application. ». Une page web devrait également s'ouvrir à l'adresse « http://localhost/ » avec le message « Cannot GET / ».

    Note: --lang est ce qui a mis NodeAtlas en français. Il n'est plus nécéssaire pour la suite.

Le Hello World

Affichons notre première page web ! Nous allons ajouter à la structure initiale un webconfig.json et une page index.htm dans le dossier des vues views/ afin de créer une route.

  1. Nous créons donc le fichier webconfig.json que nous allons alimenter comme suit :

    {
     "routes": {
         "/hello-world/": "index.htm"
     }
    }
    

    Nous venons donc de dire qu'à l'adresse « http://localhost/hello-world/ » nous afficherons le contenu de index.htm.

    Si vous aviez eu le message « NodeAtlas c'est arrêté car le port 80 est déjà écouté par une autre application. », changez alors le port d'écoute de votre application avec le webconfig.json suivant :

    {
     "httpPort": 7777,
     "routes": {
         "/hello-world/": "index.htm"
     }
    }
    

    Cette fois, c'est l'adresse « http://localhost:7777/hello-world/ » qu'il faudra afficher pour avoir le contenu de index.htm.

  2. Nous créons ensuite le fameux fichier de contenu index.htm pour obtenir l'arborescence suivante :

    project-directory/
    ├─ node_modules/
    │  ├─ node-atlas/
    │  ┊┉
    │
    ├─ views/
    │  └─ index.htm
    └─ server.js
    

    et le remplissons de ce contenu :

    <!DOCTYPE html>
    <html lang="en">
     <head>
         <meta charset="utf-8">
         <title>The Hello World Page !</title>
     </head>
     <body>
         <p>Hello World !</p>
     </body>
    </html>
    
  3. Relançons la commande précédente :

    1. En retournant dans votre invité de commande.
    2. En tapant Ctrl + C pour couper l'instance en cours
    3. En appuyant sur la touche « haut » pour ré-afficher la commande node server.js --lang fr-fr (vous pouvez à présent seulement conserver node server.js car la langue restera en fr-fr).

    Cela ouvre votre navigateur à l'adresse « http://localhost/ » (ou « http://localhost:7777/ ») avec un joli : « Cannot GET / ». Allez donc à l'addresse « /hello-world/ » comme celà : « http://localhost/hello-world/ » pour afficher votre « Hello World ! ».

Votre premier Hello World avec NodeAtlas

Il est possible, si votre page d'atterissage est « /hello-world/ », de changer votre fichier server.js comme suit :

require('node-atlas')().run({
    browse: "/hello-world/"
});

Architecture HTML multilingue

Gestion des vues et inclusions

La structure de l'exemple

La structure et le découpage que je vais vous proposer est arbitraire. NodeAtlas vous laisse la totale liberté quand à la structure et au découpage de votre rendu. Pas d'id imposé, pas de classe... rien.

Voici celle que je vous propose pour notre exemple :

  1. Le dossier du projet qui contient tous les fichiers.

    project-directory/
    
  2. Le dossier contenant tous les modules npm de votre site.

    ├─ node_modules/
    │  ├─ node-atlas/
    │  ┊┉
    
  3. Le dossier contenant tous les fichiers disponibles par demande HTTP sans nécésiter de référence de route dans le webconfig.json. Le dossier assets/.

    ├─ assets/
    │  ├─ javascripts/
    │  │  ├─ common.js
    │  │  └─ home.js
    │  ├─ stylesheets/
    │  │  ├─ common.css
    │  │  └─ home.css
    │  └─ media/
    │     └─ images/
    
  4. Le dossier contenant chaque vue d'affichage différent pour votre site.

    ├─ views/
    │  ├─ home.htm
    │  ├─ default.htm
    
  5. Le dossier contenant les composants HTML répétable sur plus d'une vue et ajouté via des include.

    │  └─ partials/
    │     ├─ head.htm
    │     ├─ header.htm
    │     ├─ footer.htm
    │     └─ foot.htm
    
  6. Les fichiers de la racines du projet. S'ajouterons à termes un README.md et un package.json.

    ├─ server.js
    └─ webconfig.json
    

Ce qui nous donne en totalité :

project-directory/
├─ node_modules/
│  ├─ node-atlas/
│  ┊┉
│
├─ assets/
│  ├─ javascripts/
│  │  ├─ common.js
│  │  └─ home.js
│  ├─ stylesheets/
│  │  ├─ common.css
│  │  └─ home.css
│  └─ media/
│     └─ images/
├─ views/
│  ├─ home.htm
│  ├─ default.htm
│  └─ partials/
│     ├─ head.htm
│     ├─ header.htm
│     ├─ footer.htm
│     └─ foot.htm
├─ server.js
└─ webconfig.json

Nous allons remplir ces fichiers, avant d'exécuter la suite. Vous pouvez télécharger cette arborescence à vide ici pour gagner du temps.

Liste des routes

Voici le fichier webconfig.json que nous allons alimenter :

{
    "languageCode": "en-gb",
    "pageNotFound": "/page-404/",
    "routes": {
        "/": "home.htm",
        "/presentation/": "default.htm",
        "/contact-us/": "default.htm",
        "/page-404/": {
            "view": "default.htm",
            "statusCode": 404
        }
    }
}

De manière à obtenir (pour le moment) :

  • Une page d'accueil derrière « http://localhost/ »,
  • Une page de présentation derrière « http://localhost/presentation/ »,
  • Une page de contact derrière « http://localhost/contact-us/ »,
  • Et une page d'erreur derrière toutes les urls ne pointant pas vers un fichier du dossier assets/.

Note : si la route —initialement une string— se transforme en Object, alors la propriété dans cet objet (représentant la string initiale) est view.

Structure des vues Home et Default

Pour commencer, nous n'aurons que deux vues différentes. Une vue présentant une liste d'éléments important à consulter et une vue permettant d'afficher un titre et du texte.

Voici donc nos deux vues :

views/default.htm

<!-- Sections communes stockées dans le dossier `views/partials/` et inclues dans notre vue. Ici la balise <head> avec les feuilles de style communes ainsi que le header. -->
<?- include('partials/head.htm') ?>
<?- include('partials/header.htm') ?>

        <section class="overview">
            <h1>Presentation</h1>

            <p>This is a presentation about subject of the website !</p>
        </section>

<!-- Sections communes stockées dans le dossier `views/partials/` et inclues dans notre vue. Ici les scripts JavaScript communs et le footer. -->
<?- include('partials/footer.htm') ?>
<?- include('partials/foot.htm') ?>

views/home.htm

<?- include('partials/head.htm') ?>

        <!-- Liste des styles CSS disponibles pour la vue courante. -->
        <link rel="stylesheet" href="stylesheets/home.css">

<?- include('partials/header.htm') ?>

        <section class="must-see">
            <h1>Not to be missed</h1>

            <ul>
                <li>
                    <h2>What is our subject ?</h2>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
                    <p><a href="./presentation/">Go to Presentation</a></p>
                </li>
                <li>
                    <h2>Contact us !</h2>
                    <p>Quibusdam eaque nemo dolorum labore dolor repellendus minus, magnam asperiores, nostrum, nisi porro, molestiae ipsa.</p>
                    <p><a href="./contact-us/">Go to Contact Information</a></p>
                </li>
                <li>
                    <h2>Welcome !</h2>
                    <p>Vero aliquam debitis, similique rerum hic asperiores.</p>
                    <p><a href="./">Go to Home</a></p>
                </li>
            </ul>
        </section>

<?- include('partials/footer.htm') ?>

        <!-- Liste des controllers JavaScript client spécifiques à la vue courante. -->
        <script type="text/javascript" src="javascripts/home.js"></script

<?- include('partials/foot.htm') ?>

et voici les 4 vue partielles communes incluse dans ces deux vues :

  1. views/partials/head.htm

    <!DOCTYPE html>
    <!-- Injection dynamique de la langue pour la route courante via `languageCode`. -->
    <html lang="<?= languageCode ?>">
     <head>
         <meta charset="utf-8">
         <title>Title of the page</title>
    
         <!-- Injection dynamique de l'url absolue du site jusqu'à sa racine. -->
         <base href="<?= urlBasePath ?>/">
    
         <!-- Liste des Frameworks CSS disponibles pour toutes les pages. -->
         <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    
         <!-- Liste des styles CSS disponibles pour toutes les pages. -->
         <link rel="stylesheet" href="stylesheets/common.css">
    
  2. views/partials/header.htm

     </head>
     <body>
         <!-- Classe spécifique à chaque layout. -->
         <div class="home layout">
             <header>
                 <h1>Website main title</h1>
             </header>
    

    Note : nous verrons dans la partie suivante comment injecter une classe de layout différente en fonction du template qui injecte le composant.

  3. views/partials/footer.htm

             <footer>
                 <p>©All rights not reserved at all !</p>
             </footer>
         </div>
    
         <!-- Liste des librairies JavaScript disponibles pour toutes les vues. -->
         <script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.min.js"></script>
    
  4. views/partials/foot.htm

         <!-- Liste des controllers JavaScript client qui affectent toutes les vues. -->
         <script type="text/javascript" src="javascripts/common.js"></script>
     </body>
    </html>
    

    N'oubliez pas de remettre votre page de lancement à la racine :

server.js

require('node-atlas')().run({
    browse: "/" // ou true
});

À présent, ré-exécutez node server.js rapidement :

  1. En retournant dans votre invité de commande.
  2. En tapant Ctrl + C pour couper l'instance en cours
  3. En appuyant sur la touche « haut » pour ré-afficher la commande node server.js.

Note : à notre niveau d'utilisation de NodeAtlas, seul un changement dans le webconfig.json nécessite un redémarrage du moteur.

Comme vous pouvez le constater, toutes vos pages ont le même titre, la même classe de layout et même pire, les pages « /presentation/ », « /contact-us/ » ou les pages d'erreurs (comme « /a-non-existing-page/ ») sont identiques... pas très pratique tout cela. Bien qu'il soit possible d'étendre la configuration dédiée de chaque page dans le webconfig lui-même comme vous allez le voir ci-dessous, la section « Gestion des variations et du multilingue » de cet article sera dédiée à cette tâche.

Étendre les routes du webconfig.json

Pour le petit exemple, si vous ne souhaitez pas activer les variations (voir plus loin dans cet article) pour quelques delta entre chaque page vous pouvez procéder comme suit :

webconfig.json

{
    "languageCode": "en-gb",
    "pageNotFound": "/page-404/",
    "routes": {
        "/": {
            "view": "home.htm",
            "_layout": "home",
            "_title": "Home Page"
        },
        "/presentation/": {
            "view": "default.htm",
            "_layout": "default",
            "_title": "Presentation"
        },
        "/contact-us/": {
            "view": "default.htm",
            "_layout": "default",
            "_title": "Contact Us"
        },
        "/page-404/": {
            "view": "default.htm",
        "statusCode": 404,
            "_layout": "default",
            "_title": "Page 404"
        }
    }
}

Note : les noms de propriété pour étendre vos routes commence par des « _ » (cela est totalement arbitraire pour l'exemple) pour éviter qu'elles n'entrent en conflit avec de futures propriétées réservées par NodeAtlas.

views/partials/header.htm

    </head>
    <body>
        <!-- Utilisation de la valeur « home » ou « default » en fonction de la route. -->
        <div class="<?- routeParameters._layout ?> layout">
            <header>
                <!-- Utilisation de la valeur « Home Page », « Presentation », « Contact Us » ou « Page 404 » en fonction de la route. -->
                <h1><?- routeParameters._title ?></h1>
            </header>

De cette manière, la classe layout et le titre seront différent en fonction de la page.

Gestion des variations et du multilingue

Étendre les routes avec vos propres variables de webconfig est plus une rustine qu'une véritable bonne pratique. Cela peut faire l'affaire pour une ou deux variables cependant le but d'une vue est d'être alimenté par des données transversales et différentes en fonction de la route : ces données sont les variations !

Mettre en place des fichiers de variations pour une même vue

Notre nouveau webconfig.json est le suivant :

{
    "languageCode": "en-gb",
    "pageNotFound": "/page-404/",
    "routes": {
        "/": {
            "view": "home.htm",
            "variation": "home.json"
        },
        "/presentation/": {
            "view": "default.htm",
            "variation": "presentation.json"
        },
        "/contact-us/": {
            "view": "default.htm",
            "variation": "contact-us.json"
        },
        "/page-404/": {
            "view": "default.htm",
            "variation": "page-404.json",
            "statusCode": 404
        }
    }
}

et nous avons donc dans notre structure le nouveau dossier :

├─ variations/
│  ├─ home.json
│  ├─ presentation.json
│  ├─ contact-us.json
│  └─ page-404.json

Vous pouvez télécharger ce complément d'arborescence à vide ici pour gagner du temps.

Cela fait que nous avons à présent des variables utilisables pour chaque vue via la propriété variation. C'est vous qui décidez quelles sont les variables que vous souhaitez vous créer pour pouvoir par la suite les utiliser dans vos vues. Voyons de plus prèt tous ses fichiers.

Avec les 3 fichiers de variations suivant :

variations/presentation.json

{
    "layout": "default presentation",
    "title": "Presentation",
    "content": "<p>This is a presentation about subject of the website !</p>"
}

variations/contact-us.json

{
    "layout": "default contact-us",
    "title": "Contact Us",
    "content": "<p>Please contact us to fake@email.here.</p>"
}

variations/page-404.json

{
    "layout": "default page-404",
    "title": "Page 404",
    "content": "<p>This page do not exist !</p>"
}

on peut alimenter la vue suivante :

views/default.html

<?- include('partials/head.htm') ?>
<?- include('partials/header.htm') ?>

        <section class="overview">
            <!-- Retourne la valeur `title` du fichier json référencé dans la propriété `variation` de la route. -->
            <h1><?- specific.title ?></h1>

            <!-- Retourne la valeur `content` du fichier json référencé dans la propriété `variation` de la route. -->
            <?- specific.content ?>
        </section>

<?- include('partials/footer.htm') ?>
<?- include('partials/foot.htm') ?>

ainsi le contenu des pages est différent en fonction de si l'on appel :

  • « http://localhost/presentation/ »,
  • « http://localhost/contact-us/ » ou
  • Une page qui n'existe pas « http://localhost/a-non-existing-page/ ».

De la même manière le fichier de variation :

variations/home.json

{
    "layout": "home",
    "title": "Home Page",
    "overview": [{
        "title": "What is our subject ?",
        "content": "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>",
        "link": {
            "href": "./presentation/",
            "content": "Go to Presentation"
        }
    }, {
        "title": "Contact us !",
        "content": "<p>Quibusdam eaque nemo dolorum labore dolor repellendus minus, magnam asperiores, nostrum, nisi porro, molestiae ipsa.</p>",
        "link": {
            "href": "./contact-us/",
            "content": "Go to Contact Information"
        }
    }, {
        "title": "Welcome !",
        "content": "<p>Vero aliquam debitis, similique rerum hic asperiores.</p>",
        "link": {
            "href": "./",
            "content": "Go to Home"
        }
    }]
}

alimente le template :

views/home.html

<?- include('partials/head.htm') ?>

        <link rel="stylesheet" href="stylesheets/home.css">

<?- include('partials/header.htm') ?>

        <section class="must-see">

            <!-- Le tiret indique que l'on veut afficher la valeur et interpréter les éventuels éléments HTML qu'elle contient. -->
            <h1><?- specific.title ?></h1>

            <ul>

                <!-- Voici comment boucler sur le tableau `specific.overview` du fichier de variation. -->
                <? for (var i = 0, l = specific.overview.length; i < l; i++) { ?>
                <li>
                    <h2><?- specific.overview[i].title ?></h2>
                    <?- specific.overview[i].content ?>

                    <!-- L'égale indique que l'on veut afficher la valeur sans interpréter les éventuels éléments HTML qu'elle contient. -->
                    <p><a href=".<?= specific.overview[i].link.href ?>"><?- specific.overview[i].link.content ?></a></p>
                </li>
                <? } ?>
            </ul>
        </section>

<?- include('partials/footer.htm') ?>

        <script type="text/javascript" src="javascripts/home.js"></script

<?- include('partials/foot.htm') ?>

À présent, ré-exécutez node server.js pour tester.

  1. En retournant dans votre invité de commande.
  2. En tapant Ctrl + C pour couper l'instance en cours
  3. En appuyant sur la touche « haut » pour ré-afficher la commande node server.js.

Gestion de sites multilingues avec les variations

Avec cette mécanique, nous pouvons facilement gérer des sites en plusieurs langues. Pour cela nous allons activer deux mécanismes :

  • La possibilité d'avoir un fichier de variation commun à l'ensemble des pages.
  • La possiblilité d'indiquer un languageCode différent en fonction de la route utilisée.

Voyons cela avec le fichier webconfig.json suivant :

{
    "languageCode": "en-gb",
    "pageNotFound": "/page-404/",
    "variation": "common.json",
    "routes": {
        "/": {
            "view": "home.htm",
            "variation": "home.json"
        },
        "/presentation/": {
            "view": "default.htm",
            "variation": "presentation.json"
        },
        "/contact-us/": {
            "view": "default.htm",
            "variation": "contact-us.json"
        },
        "/francais/": {
            "view": "home.htm",
            "variation": "home.json",
            "languageCode": "fr-fr"
        },
        "/francais/presentation/": {
            "view": "default.htm",
            "variation": "presentation.json",
            "languageCode": "fr-fr"
        },
        "/francais/contactez-nous/": {
            "view": "default.htm",
            "variation": "contact-us.json",
            "languageCode": "fr-fr"
        },
        "/francais/*": {
            "view": "default.htm",
            "variation": "page-404.json",
            "languageCode": "fr-fr",
        "statusCode": 404
        },
        "/page-404/": {
            "view": "default.htm",
            "variation": "page-404.json",
            "statusCode": 404
        }
    }
}

et le nouveau dossier de variation suivant :

├─ variations/
│  ├─ common.json
│  ├─ home.json
│  ├─ presentation.json
│  ├─ contact-us.json
│  ├─ page-404.json
│  └─ fr-fr/
│     ├─ common.json
│     ├─ home.json
│     ├─ presentation.json
│     ├─ contact-us.json
│     └─ page-404.json

Vous pouvez télécharger ce complément d'arborescence à vide ici pour gagner du temps.

avec le nouveau fichier en-gb :

variations/common.json

{
    "title": "My first Website !",
    "copyright": "©All rights not reserved at all !"
}

et son équivalent fr-fr :

variations/fr-fr/common.json

{
    "title": "Mon premier site web !",
    "copyright": "©Tous les droits ne sont pas réservés du tout !"
}

et les versions complètes en français de :

variations/fr-fr/presentation.json

{
    "layout": "default presentation",
    "title": "Présentation",
    "content": "<p>Voici une présentation à propos du site de notre projet.</p>"
}

variations/fr-fr/contact-us.json

{
    "layout": "default contact-us",
    "title": "Contactez-nous",
    "content": "<p>Merci de nous contacter à l'adresse fake@email.here.</p>"
}

variations/fr-fr/page-404.json

{
    "layout": "default page-404",
    "title": "Page 404",
    "content": "<p>Cette page n'existe pas !</p>"
}

variations/fr-fr/home.json

{
    "layout": "home",
    "title": "Page d'accueil",
    "overview": [{
        "title": "Qu'est-ce que notre projet ?",
        "link": {
            "href": "./francais/presentation/",
            "content": "Allez à la présentation"
        }
    }, {
        "title": "Contactez-nous !",
        "link": {
            "href": "./francais/contactez-nous/",
            "content": "Aller aux informations de contact"
        }
    }, {
        "title": "Bienvenue !",
        "link": {
            "href": "./francais/",
            "content": "Aller à l'accueil"
        }
    }]
}

Note : vous remarquerez que les valeurs de specific.overview[i].content n'ont pas été traduites. Dans ce cas là, c'est la valeur du dossier parent qui sera prise en compte, dans notre cas la version en-gb.

En ce qui concerne les vues, pas de changement puisqu'ils avaient déjà été effectués. Cependant, nous allons rendre dynamique les valeurs dans nos vues partielles partials/header.htm et partials/footer.htm à partir de notre fichier de vartiation common.json.

views/partials/header.htm

    </head>
    <body>

        <!-- Cette valeur sera différente en fonction de la route car elle provient d'un fichier spécifique. -->
        <div class="<?= specific.layout ?> layout">
            <header>

                <!-- Cette valeur sera identique pour toutes les routes car elle provient d'un fichier commun. -->
                <h1><?- common.title ?></h1>
            </header>

views/partials/footer.htm

            <!-- Cette valeur sera identique pour toutes les routes car elle provient d'un fichier commun. -->
            <footer>
                <p><?- common.copyright ?></p>
            </footer>
        </div>
        <script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.min.js"></script>

À présent, ré-exécutez node server.js pour tester.

Pour aller plus loin

Des urls dynamiques

Il ne vous aura peut-être pas échappé que si vous changez l'intégralité de vos urls dans le fichier webconfig.json, tous vos liens ne seront plus valides à travers tous vos fichiers de variations. Voici la marche à suivre pour rendre tous vos liens dynamiques !

Changeons notre webconfig.json comme suit (pageNotFound et chaque clé dans routes) :

{
    "languageCode": "en-gb",
    "pageNotFound": "error",
    "variation": "common.json",
    "routes": {
        "home": {
            "url": "/",
            "view": "home.htm",
            "variation": "home.json"
        },
        "presentation": {
            "url": "/presentation/",
            "view": "default.htm",
            "variation": "presentation.json"
        },
        "contact-us": {
            "url": "/contact-us/",
            "view": "default.htm",
            "variation": "contact-us.json"
        },
        "home-fr-fr": {
            "url": "/francais/",
            "view": "home.htm",
            "variation": "home.json",
            "languageCode": "fr-fr"
        },
        "presentation-fr-fr": {
            "url": "/francais/presentation/",
            "view": "default.htm",
            "variation": "presentation.json",
            "languageCode": "fr-fr"
        },
        "contact-us-fr-fr": {
            "url": "/francais/contactez-nous/",
            "view": "default.htm",
            "variation": "contact-us.json",
            "languageCode": "fr-fr"
        },
        "error-fr-fr": {
            "url": "/francais/*",
            "view": "default.htm",
            "variation": "page-404.json",
            "languageCode": "fr-fr",
            "statusCode": 404
        },
        "error": {
            "url": "/page-404/",
            "view": "default.htm",
            "variation": "page-404.json",
            "statusCode": 404
        }
    }
}

et voyons les modifications d'appel pour les liens dans la vue home.htm :

views/home.html

<?- include('partials/head.htm') ?>

        <link rel="stylesheet" href="stylesheets/home.css">

<?- include('partials/header.htm') ?>

        <section class="must-see">

            <h1><?- specific.title ?></h1>

            <ul>
                <? for (var i = 0, l = specific.overview.length; i < l; i++) { ?>
                <li>
                    <h2><?- specific.overview[i].title ?></h2>
                    <?- specific.overview[i].content ?>

                    <!-- On réclame la clé `specific.overview[i].link.href` dans la liste des routes `webconfig.routes` pour en afficher son `url`. -->
                    <p><a href=".<?= webconfig.routes[specific.overview[i].link.href].url ?>"><?- specific.overview[i].link.content ?></a></p>
                </li>
                <? } ?>
            </ul>
        </section>

<?- include('partials/footer.htm') ?>

        <script type="text/javascript" src="javascripts/home.js"></script

<?- include('partials/foot.htm') ?>

Il faudra ensuite placer les bonnes clés dans les propriétés overview[i].link.href de vos fichiers common.js :

variations/home.json

{
    "layout": "home",
    "title": "Home Page",
    "overview": [{
        "title": "What is our subject ?",
        "content": "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
        "link": {
            "href": "presentation",
            "content": "Go to Presentation"
        }
    }, {
        "title": "Contact us !",
        "content": "Quibusdam eaque nemo dolorum labore dolor repellendus minus, magnam asperiores, nostrum, nisi porro, molestiae ipsa.",
        "link": {
            "href": "contact-us",
            "content": "Go to Contact Information"
        }
    }, {
        "title": "Welcome !",
        "content": "Vero aliquam debitis, similique rerum hic asperiores.",
        "link": {
            "href": "home",
            "content": "Go to Home"
        }
    }]
}

variations/fr-fr/home.json

{
    "layout": "home",
    "title": "Page d'accueil",
    "overview": [{
        "title": "Qu'est-ce que notre projet ?",
        "link": {
            "href": "presentation-fr-fr",
            "content": "Allez à la présentation"
        }
    }, {
        "title": "Contactez-nous !",
        "link": {
            "href": "contact-us-fr-fr",
            "content": "Aller aux informations de contact"
        }
    }, {
        "title": "Bienvenue !",
        "link": {
            "href": "home-fr-fr",
            "content": "Aller à l'accueil"
        }
    }]
}

À présent, ré-exécutez node server.js pour tester.

Vous pouvez récupérer l'intégralité du code de cet article dans cette archive pour tester.

D'autres bonnes pratiques

Vous trouverez d'autres fonctionnalités de NodeAtlas sur le site officiel de NodeAtlas.

À présent passons à notre second article pour bien débuter avec NodeAtlas et dédiés :