Templates

3

Traduction complétée à

Au programme de ce chapitre :

  • Découvrir le langage de templating de Meteor, Spacebars.
  • Créer vos trois premiers templates.
  • Comment fonctionne les managers de Meteor.
  • Avoir un prototype de base fonctionnel avec des données statiques.
  • Pour faciliter le développement dans Meteor, nous allons adopter une approche de l'extérieur vers l'intérieur. En d'autres termes, nous allons créer une simple page html/javascript, puis nous la rattacherons à la mécanique interne de l'application plus tard.

    Ce qui veut dire que dans ce chapitre nous nous occuperons de ce qu'il se passe dans le répertoire /client.

    Si vous ne l'avez pas déjà fait, créez un nouveau fichier appelé main.html dans votre répertoire /client et insérez le code suivant :

    <head>
      <title>Microscope</title>
    </head>
    <body>
      <div class="container">
        <header class="navbar navbar-default" role="navigation">
          <div class="navbar-header">
            <a class="navbar-brand" href="/">Microscope</a>
          </div>
        </header>
        <div id="main">
          {{> postsList}}
        </div>
      </div>
    </body>
    
    client/main.html

    Ce sera le template principal de notre application. Comme vous pouvez le voir c'est du langage HTML excepté pour la balise d'inclusion de template {{> postsList}}, qui est un point d'insertion pour le template postsList que nous verrons bientôt. Nous allons maintenant créer deux templates supplémentaires.

    Les templates Meteor

    En son cœur, un site d'actualités social est composé d'articles organisés en listes, et c'est exactement de cette façon que nous allons organiser nos templates.

    Créons un répertoire /templates dans /client. C'est ici que nous mettrons tous nos templates, et pour garder les choses en ordre nous allons également créer /posts dans /templates juste pour nos templates relatifs aux articles (posts).

    Recherche de fichiers

    Meteor est génial pour trouver les fichiers. Peu importe où vous mettez votre code dans le répertoire /client, Meteor le trouvera et le compilera proprement. Ce qui signifie que vous n'avez jamais besoin d'écrire manuellement des chemins d'inclusion (include) pour les fichiers javascript ou CSS.

    Ça signifie également que vous pourriez aussi bien mettre tous vos fichiers dans le même répertoire, ou même tout votre code dans le même fichier. Mais sachant que Meteor compilera tout dans un seul fichier minifié de toute façon, nous garderons plutôt les choses bien organisées et utiliserons une structure de fichier la plus claire possible.

    Nous sommes finalement prêt pour créer notre second template. Dans client/templates/posts, créez posts_list.html :

    <template name="postsList">
      <div class="posts">
        {{#each posts}}
          {{> postItem}}
        {{/each}}
      </div>
    </template>
    
    client/templates/posts/posts_list.html

    Et post_item.html :

    <template name="postItem">
      <div class="post">
        <div class="post-content">
          <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
        </div>
      </div>
    </template>
    
    client/templates/posts/post_item.html

    Notez l'attribut name="postsList" de la balise template. C'est le nom qui sera utilisé par Meteor pour garder la trace de quel template va où (le nom du fichier n'est pas important).

    Il est temps de présenter le système de templating de Meteor, Spacebars. Spacebars est du html simple, avec trois choses en plus : inclusions (parfois désignée sous le nom de “partials”), expressions et block helpers.

    Les Inclusions utilisent la syntaxe {{> templateName}}, et indiquent simplement à Meteor de remplacer le champ par le template du même nom (dans notre cas postItem).

    Les Expressions telles que {{title}} appellent une propriété de l'objet courant, ou retourne la valeur du template helper comme défini dans le template manager courant (plus d'information sur ce sujet plus tard).

    Finalement, les block helpers sont des balises spéciales qui contrôlent le flux du template, tels que {{#each}}...{{/each}} ou {{#if}}...{{/if}}.

    Aller plus loin

    Vous pouvez consulter la documentation Spacebars si vous voulez en apprendre plus à propos de Spacebars.

    Armé de cette connaissance, vous pouvez dorénavant comprendre ce qui se passe ici.

    Premièrement, dans le template postsList, nous faisons des itérations sur un objet posts avec le block helper {{#each}}…{{/each}}. Ensuite, pour chaque itération nous allons inclure le template postItem.

    D'où vient cet objet posts ? Bonne question. C'est un template helper ; vous pouvez vous l'imaginer comme un substitut à un contenu dynamique.

    Le template postItem lui-même est assez simple. Il utilise trois expression : {{url}} et {{title}} retournent des propriétés du document, et {{domain}} appelle un template helper.

    Template Managers

    Jusqu'à maintenant, nous avons travaillé avec Spacebars, qui est du HTML avec quelques balises parsemées dedans. Contrairement aux autres langages tel que PHP (ou même des pages HTML classiques, qui contiennent du javascript), Meteor garde les templates et leur logique séparés, et ces templates ne font rien par eux-même.

    Afin d'exister, un template a besoin de helpers. Vous pouvez imaginer ces helpers comme un chef qui prend des ingrédients crus (vos données) et les prépare, avant de dresser une assiette (les templates) qu'il va donner à un serveur qui va ensuite vous les présenter.

    En d'autres termes, pendant que le rôle du template est limité à l'affichage et aux itérations dans les variables, c'est celui des helpers qui fait en réalité le gros du travail en assignant une valeur à chaque variable.

    Des contrôleurs ?

    Il peut sembler tentant de penser aux fichiers contenant tous les helpers d'un template comme une sorte de “contrôleur” (controller). Mais cela peut être ambigu, puisque les “contrôleurs” (du moins du point de vue MVC) ont habituellement un rôle légèrement différent.

    Nous avons donc décidé de ne pas utiliser cette terminologie et de nous référer simplement à “les helpers du template” ou à “la logique du template” lorsque nous parlons du code JavaScript associé au template.

    Pour garder les choses simples, nous allons nommer les fichiers contenant les helpers comme le template, mais avec une extension .js. Créons donc directement posts_list.js dans client/templates/posts et commençons à construire notre premier helper :

    var postsData = [
      {
        title: 'Introducing Telescope',
        url: 'http://sachagreif.com/introducing-telescope/'
      },
      {
        title: 'Meteor',
        url: 'http://meteor.com'
      },
      {
        title: 'The Meteor Book',
        url: 'http://themeteorbook.com'
      }
    ];
    Template.postsList.helpers({
      posts: postsData
    });
    
    client/templates/posts/posts_list.js

    Si vous l'avez fait correctement, vous devriez avoir quelque choses de similaire à ça dans votre navigateur :

    Nos premiers templates avec données statiques
    Nos premiers templates avec données statiques

    Nous faisons deux choses ici. Premièrement, nous insérons des données prototype dans le tableau postsData. Ces données viendraient normalement de la base de données, mais comme nous n'avons pas encore vu comment faire (prochain chapitre) nous allons tricher en utilisant des données statiques.

    Deuxièmement, nous utilisons la fonction Template.myTemplate.helpers() pour définir un template helper appelé posts qui retourne le tableau postsData défini auparavant.

    Si vous vous souvenez, nous utilisons ce helper de posts dans notre template postsList :

    <template name="postsList">
      <div class="posts page">
        {{#each posts}}
          {{> postItem}}
        {{/each}}
      </div>
    </template>
    
    client/templates/posts/posts_list.html

    Définir le helper de posts implique qu'il est maintenant disponible pour notre template, donc notre template sera capable de faire des itérations sur le tableau postsData, et d'envoyer chaque objet vers le template postItem.

    Commit 3-1

    Avec le template basique de posts list et les données sta…

    Le helper domain

    De même, nous allons créer post_item.js pour y renseigner la logique du template de postItem :

    Template.postItem.helpers({
      domain: function() {
        var a = document.createElement('a');
        a.href = this.url;
        return a.hostname;
      }
    });
    
    client/templates/posts/post_item.js

    Cette fois la valeur du helper domain n'est pas un tableau, mais une fonction anonyme. Ce modèle est bien plus commun (et plus utile) comparé à nos précédents exemples de données simples.

    Afficher les domaines pour chaque lien.
    Afficher les domaines pour chaque lien.

    Le helper domain prend une URL et retourne son domaine via un peu de magie JavaScript. Mais où prend-il l'url dans un premier temps ?

    Pour répondre à cette question nous avons besoin de revenir à notre template posts_list.html. Le block helper {{#each}} ne fais pas seulement des itérations sur notre tableau, il insère également les valeurs dans this à l'intérieur du bloc de l'objet itéré.

    Ça signifie qu'à l'intérieur des deux balises {{#each}}, chaque article (post) est assigné à this successivement, et ça s'étend dans le manager du template inclus (post_item.js).

    Nous comprenons maintenant pourquoi this.url retourne l'URL de l'article courant. De plus, si nous utilisons {{title}} et {{url}} dans notre template post_item.html, Meteor sait ce que veut dire this.title et this.url et retourne les valeurs correctes.

    Commit 3-2

    Configurer un helper `domain` à partir du `postItem`.

    Magie JavaScript

    Bien que ce ne soit pas spécifique à Meteor, voici une petite explication de “Magie JavaScript”. Premièrement, nous créons une balise (‘a’) avec ancre vide et la stockons en mémoire.

    Nous modifions ensuite l'attribut href pour être égal à l'URL de l'article courant (comme nous venons de le voir, l'objet en cours de traitement se trouve dans un helper this).

    Finalement, nous prenons avantage de la propriété spéciale hostname de l'élément a pour récupérer le nom de domaine du lien sans le reste de l'URL.

    Si vous avez suivi correctement, vous devriez voir une liste d'articles dans votre navigateur. C'est juste une liste de données statiques, donc ça ne tient pas compte des avantages des fonctionnalités temps réel de Meteor. Nous verrons comment changer ça dans le chapitre suivant !

    Hot Code Reload

    Vous avez pu noter que vous n'aviez même pas eu besoin de recharger manuellement la fenêtre de notre navigateur quand vous avez modifié vos fichiers.

    C'est parce que Meteor traque tous les fichiers dans le répertoire de votre projet, et rafraîchit automatiquement le navigateur quand il détecte une modification sur l'un d'entre eux.

    Le Hot Code Reload de Meteor est très intelligent, en préservant même l'état de votre application entre deux rafraîchissements !