Templates

3

Percentuale Tradotta

In questo capitolo imparerai:

  • Utilizzare il linguaggio di templating di Meteor, Spacebars.
  • Creare i tuoi primi 3 template.
  • Come funzionano i manager in Meteor.
  • Ottenere un prototipo base utilizzando dati statici.
  • Per rendere semplice l'apprendimento dello sviluppo in Meteor, adotteremo un approccio dall'esterno. In altre parole realizzeremo prima una semplice struttura in HTML/JavaScript e la integreremo con le funzionalità dell'applicazione solo in un secondo momento.

    Ciò significa che in questo capitolo ci preoccuperemo solamente di ciò che accade all'interno della cartella /client.

    Creiamo un nuovo file chiamato main.html all'interno della cartella /client e inseriamoci il seguente codice:

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

    Questo sarà il template principale della nostra applicazione. Come potete notare si tratta di semplice HTML ad eccezione del tag {{> postsList}}, che rappresenta il punto di inserimento del template postsList che vedremo a breve. Per ora creiamo altri 2 template.

    Template in Meteor

    Alla base, un sito di notizie social è composto di post organizzati in liste, e questo è esattamente il modo in cui andremo ad organizzare i nostri template.

    Creiamo un cartella /views all'interno della cartella /client. In questa cartella andremo a posizionare tutti i nostri template e per mantenere la struttura ordinata creiamo una cartella /posts all'interno di /views solo per i template relativi ai post.

    Come trovare i file

    Meteor è grandioso a trovare i file. Non importa dove e come mettete il codice all'interno della cartella /client, Meteor lo troverà e lo compilerà correttamente. Questo significa che non dovrete mai inserire manualmente i riferimenti ai file JavaScript e CSS.

    Questo significa anche che potete inserire tutti i vostri file nella stessa cartella, o anche tutto il vostro codice in un solo file, ma visto che Meteor compilerà tutto in un singolo file minificato, è meglio tenere tutto ben organizzato in una struttura file ordinata.

    Creiamo finalmente il nostro secondo template. Dentro client/views/posts, creiamo posts_list.html:

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

    E 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/views/posts/post_item.html

    Notate l'attributo name="postsList" dell'elemento template. Questo è il nome che viene utilizzato da Meteor per tenere traccia di dove vanno inseriti i vari template.

    È il momento di introdurre il sistema di template di Meteor, Spacebars. Spacebars è semplice HTML, con l'aggiunta di tre particolarità: parziali, espressioni e blocchi di controllo.

    I parziali usano la sintassi {{> templateName}}, e dicono semplicemente a Meteor di sostituire il parziale con il template con lo stesso nome (nel nostro caso postItem).

    Le espressioni come {{title}} possono richiamare sia una proprietà dell'oggetto attuale, o il valore restituito da un helper del template come definito nel manager del template attuale (parleremo meglio più avanti di questo).

    Infine, i blocchi di controllo sono tag speciali che controllano il flusso del template come {{#each}}…{{/each}} o {{#if}}…{{/if}}.

    Più informazioni

    Potete far riferimento alla documentazione di Spacebars se volete imparare di più su Spacebars.

    Armati di queste nuove conoscenze, possiamo facilmente capire cosa sta succedendo.

    Come prima cosa nel template postsList, stiamo iterando su un oggetto posts grazie al blocco di controllo {{#each}}…{{/each}}. Successivamente, per ogni iterazione, includiamo il template postItem.

    Da dove arriva questo oggetto posts? Buona domanda. Si tratta di un helper di template che definiremo più avanti quando di occuperemo dei manager di template.

    Il template postItem è abbastanza lineare. Usa solo tre espressioni: {{url}} e {{title}} ritornano le proprietà del documento, mentre {{domain}} chiama un helper del template.

    Abbiamo nominato molte volte gli “helper del template” in questo capitolo senza in realtà spiegare come funzionano. Prima di poter riparare a questa mancanza dobbiamo parlare dei manager.

    Manager dei Template

    Fino ad ora abbiamo lavorato con Spacebars, che non è altro che puro HTML con l'aggiunta di qualche tag speciale. Contrariamente ad altri linguaggi come PHP (o anche normali pagine HTML, che possono includere JavaScript), Meteor tiene i template e la logica separati, e i template da soli non sono sufficienti.

    Per prendere vita, un template ha bisogno di un manager. Potete immaginare un manager come uno chef che prende ingredienti grezzi (i vostri dati) e li prepara, prima di consegnare il piatto pronto al cameriere (il template) che ve lo presenta una volta pronto.

    In altre parole, mentre il ruolo del template è limitato al mostrare o iterare su delle variabili, il manager è colui che si occupa del lavoro duro, assegnando un valore ad ogni variabile.

    Manager?

    Quando abbiamo chiesto ad altri sviluppatori Meteor come avrebbero chiamato i manager di template, metà ha risposto “controller”, e metà “quei file dove metto il mio codice JavaScript”.

    I manager non sono esattamente controller (per lo meno non nel senso di controller MVC) e “QFDMIMCJ” non è certo un acronimo accattivante, così abbiamo accantonato entrambe le proposte.

    Dato che avevamo comunque bisogno di indicare in modo comprensibile ciò di cui stavamo parlando, abbiamo optato per chiamarli “manager”, termine che non ha nessun particolare significato all'interno di altri framework web e quindi più comodo per rappresentare qualcosa di nuovo.

    Per mantenere una certa semplicità, useremo la convenzione di nominare i manager in base al template, con la differenza di avere l'estensione .js. Creiamo quindi posts_list.js all'interno di /client/views/posts e iniziamo a scrivere il nostro primo manager:

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

    Se avete fatto correttamente, dovreste vedere qualcosa di simile nel vostro browser:

    Il nostro primo template con dati statici
    Il nostro primo template con dati statici

    Commit 3-1

    Aggiunto template di base della lista dei post e alcuni d…

    In questo codice stiamo facendo due cose. Come prima cosa stiamo inserendo dati di esempio come schema di base nell'array postsData. Questi dati normalmente verrebbero dal database ma dal momento che non abbiamo ancora visto come fare (lo faremo nel prossimo capitolo) stiamo “bluffando” utilizzando dei dati statici.

    In secondo luogo, stiamo utilizzando la funzione di Meteor Template.myTemplate.helpers() per definire un helper del template chiamato posts che semplicemente ci restituisce l'array postsData.

    Definendo l'helper posts, lo rendiamo disponibile al nostro template:

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

    In questo modo, il template potrà iterare sull'array postsData ed inviare ogni oggetto contenuto al suo interno al template postItem.

    Il valore di “this”

    Creiamo ora il manager post_item.js:

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

    Commit 3-2

    Setup a `domain` helper on the `postItem`.

    Questa volta il valore del nostro helper domain non è un array, ma una funzione anonima. Questo pattern è molto più diffuso (e utile) se paragonato al nostro precedente esempio con semplici dati statici.

    Visualizzazione del dominio di ogni link.
    Visualizzazione del dominio di ogni link.

    L'helper domain riceve un URL e ne restituisce il dominio tramite un po’ di magia in JavaScript. Ma da dove proviene questo URL?

    Per rispondere a questa domanda dobbiamo tornare al nostro template posts_list.html. Il blocco di controllo {{#each}} non solo itera sul nostro array ma definisce il valore di this sull'oggetto iterato all'interno del blocco.

    Questo significa che all'interno dei tag {{#each}}, ogni post è assegnato al valore di this ad ogni iterazione, e si estende automaticamente all'interno del manager del template incluso (post_item.js).

    Ora possiamo capire perché this.url restituisce l'URL dell'attuale post. E inoltre, se usiamo {{title}} e {{url}} all'interno del nostro template post_item.html, Meteor sa che si tratta in realtà di this.title e this.url e ci restituisce i valori corretti.

    JavaScript Magic

    Sebbene non sia proprio di Meteor, di seguito trovate una veloce spiegazione del precedente pizzico di “magia JavaScript”. Come prima cosa, creiamo un elemento HTML vuoto, (a), e lo teniamo in memoria.

    Definiamo poi il valore del suo attributo href tramite il valore dell'URL del post attuale (come abbiamo appena visto, in un helper this è l'oggetto sul quale stiamo al momento operando).

    Infine sfruttiamo la proprietà speciale dell'elemento a, hostname, per recuperare il nome del dominio del link senza il resto dell'URL.

    Se avete seguito i passaggi correttamente, dovreste vedere una lista di post nel vostro browser. Questa lista è formata solo da dati statici, perciò non si avvale ancora delle caratteristiche in tempo reale di Meteor. Vi mostreremo come modificare questa ‘mancanza’ nel prossimo capitolo!

    Ricaricamento del codice

    Vi sarete forse accorti che non dovete nemmeno ricaricare il vostro browser ogni volta che modificate un file.

    Questo avviene perché Meteor traccia tutti i file all'interno della cartella del progetto e ricarica automaticamente il browser ogni volta che si accorge di una modifica in uno qualsiasi di essi.

    Il ricaricamento del codice di Meteor è piuttosto intelligente, infatti mantiene lo stato della vostra applicazione anche nel mezzo di due ricaricamenti!