Jak používat Jade a řídítka v Express.js

Nenáviděl jsem Jade stejně jako mnoho jiných vývojářů Node.js. Ale změnil jsem se o 180 poté, co jsem si uvědomil, že má spoustu funkcí.

Ve Storify a DocuSign jsme použili Jade pro VŠECHNO. Jade jsme používali i v prohlížeči. Existuje malý trik zvaný Jade-Browser. Byl vyvinut lidmi ze Storify. Chvíli jsem to udržoval.

Legrační je, že tým DocuSign používal Jade-browser dávno předtím, než mě potkal. Přísahají, že mě najali, aniž by věděli, že jsem v té knihovně zapletený. :-)

Každopádně poté, co jsme se v předchozích příspěvcích zabývali Jade a řidítky, je čas je použít a udělat skutečnou práci. V tomto příspěvku se budu zabývat:

  • Použití Jade a Handlebars v Express.js 4
  • Projekt:přidání šablon Jade do blogu

Ve výchozím nastavení Express.js 4.x (a 3.x) používá buď rozšíření šablony poskytnuté res.render nebo výchozí rozšíření nastavené pomocí view engine nastavení pro vyvolání require a __express metody v knihovně šablon. Jinými slovy, má-li Express.js používat knihovnu šablonového modulu, musí mít tato knihovna __express metoda.

Když knihovna nástroje šablon neposkytuje __express method , nebo podobný s (path , options , callback )parametry, doporučujeme používat Consolidate.js (https://github.com/visionmedia/consolidate.js/).

Zde je rychlý příklad Consolidate.js pro Express.js 4 (verze 4.2.0 a Consolidate verze je 0.10.0):

var express = require('express'),
  cons = require('consolidate'),
  app = express()

app.engine('html', cons.swig)

app.set('view engine', 'html')
app.set('views', __dirname + '/views')

var platforms = [
  { name: 'node' },
  { name: 'ruby' },
  { name: 'python' }
]

app.get('/', function(req, res){
  res.render('index', {
    title: 'Consolidate This'
  })
})
app.get('/platforms', function(req, res){
  res.render('platforms', {
    title: 'Platforms',
    platforms: platforms
  })
})

app.listen(3000)
console.log('Express server listening on port 3000')

Zdrojový kód je obvykle v úložišti GitHub a fragment je v
ch4/consolidate složka.

Další informace o tom, jak nakonfigurovat nastavení Express.js a používat Consolidate.js, najdete v knize Pro Express.js 4 (Apress, 2014).

Jade and Express.js

Jade je po vybalení kompatibilní s Express.js (ve skutečnosti je to výchozí volba), takže pro použití Jade s Express.js stačí nainstalovat modul šablonového modulu jade (https://www.npmjs.org /package/jade) a poskytněte rozšíření Express.js prostřednictvím view engine nastavení).

Například v souboru hlavního serveru nastavíme nastavení:

app.set('view engine', 'jade');

■ Poznámka Pokud používáte $ express <app_name> nástroj příkazového řádku, můžete přidat možnost podpory motoru, tj.–e možnost pro EJS a –H pro Hogana. Tím se do vašeho nového projektu automaticky přidá EJS nebo Hogan. Bez jedné z těchto možností bude expresní generátor (verze 4.0.0–4.2.0) používat Jade.

V souboru trasy můžeme zavolat šablonu – například views/page.jade  (views název složky je další výchozí nastavení Express.js, které lze přepsat pomocí
view nastavení):

[Sidenote]

Čtení blogových příspěvků je dobré, ale sledování videokurzů je ještě lepší, protože jsou poutavější.

Mnoho vývojářů si stěžovalo, že na Node je nedostatek dostupného kvalitního videomateriálu. Sledování videí na YouTube je rušivé a platit 500 $ za videokurz Node je šílené!

Jděte se podívat na Node University, která má na Node ZDARMA videokurzy:node.university.

[Konec vedlejší poznámky]

app.get('/page', function(req, res, next){
  //get the data dynamically
  res.render('page', data);
});

Pokud neuvedeme views engine nastavení, pak musí být rozšíření explicitně předáno res.render() :

res.render('page.jade', data);

Řídítka a Express.js

Na rozdíl od Jade knihovna Handlebars z http://handlebarsjs.com/ nepřichází s metodou __express, ale existuje několik možností, jak zajistit, aby Handlebars fungovaly s Express.js:

  • consolidate :švýcarský armádní nůž knihoven šablon Express.js (zobrazeno výše)
  • hbs (https://github.com/donpark/hbs):wrapper knihovna pro Handlebars
  • express-Handlebars (file://pchns-f01/TECHNOLOGY/BPR/Techutilities/Apress/Apress%20Outline/express3-handlebars ):navzdory názvu by tento modul měl fungovat dobře s Express.js 4 i s verzí 3.x

Zde je návod, jak můžeme použít hbs přístup (rozšíření hbs ). Uvnitř typického kódu aplikace Express.js (tj. konfigurační sekce hlavního souboru, kterou spustíme s $ node příkaz) napište následující příkazy:

...
app.set('view engine', 'hbs');
...

Nebo, pokud je vhodnější jiné rozšíření, například html , vidíme následující:

...
app.set('view engine', 'html');
pp.engine('html', require('hbs').__express); 
...

express3-handlebars použití přístupu je následující:

...
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
...

Projekt:Přidání nefritových šablon na blog

Nakonec můžeme pokračovat s blogem. V této sekci přidáváme hlavní stránky pomocí Jade a přidáváme rozvržení a některé části:

  • layout.jade :globální šablona pro celou aplikaci
  • index.jade :domovská stránka se seznamem příspěvků
  • article.jade :stránka jednotlivých článků
  • login.jade :stránka s přihlašovacím formulářem
  • post.jade :stránka pro přidání nového článku
  • admin.jade :stránka pro správu článků po přihlášení

Demo, kam zapojíme databázi MongoDB, je v ch5 složka praktického uzlu úložiště GitHub:https://github.com/azat-co/practicalnode. Zdrojový kód šablon Jade je tedy úplně stejný jako v tomto projektu GitHub. Neváhejte jej zkopírovat odtud nebo postupujte podle pokynů níže.

layout.jade

Otevřeme projekt, kde jsme skončili v ch3 z https://github.com/azat-co/practicalnode a přidejte layout.jade s prohlášením o typu dokumentu:

doctype html

■ Poznámka doctype 5 byl zastaralý kolem verze 1.0. Nyní můžeme přidat hlavní značky stránky:

html
  head

Název každé stránky pochází z appTitle proměnná (neboli místní):

title= appTitle

Poté v head uvedeme seznam všech prostředků front-end, které potřebujeme pro celou aplikaci (na každé stránce):

script(type="text/javascript", src="js/jquery-2.0.3.min.js")
link(rel='stylesheet', href='https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/css/bootstrap.min.css')
link(rel="stylesheet", href="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/css/bootstrap-theme.min.css")
link(rel="stylesheet", href="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/style.css")
script(type="text/javascript", src="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/js/bootstrap.min.js")
script(type="text/javascript", src="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/js/blog.js")
meta(name="viewport", content="width=device-width, initial-scale=1.0")

Hlavní obsah žije v body který má stejnou úroveň odsazení jako head :

body

Uvnitř těla napíšeme ID a několik tříd pro styly, které přidáme později:

#wrap
  .container

appTitle hodnota se tiskne dynamicky, ale p.lead prvek má pouze texty:

h1.page-header= appTitle
p.lead Welcome to example from Express.js Experience by&nbsp;
a(href="http://twitter.com/azat_co") @azat_co
|. Please enjoy.

block sekce mohou být přepsány dětskými šablonami (šablony, které rozšiřují tento soubor):

block page
block header
  div

Nabídka je částečná (tj. zahrnutí), která je uložena v views/includes složku. Všimněte si absence uvozovek:

include includes/menu

V tomto bloku můžeme zobrazit zprávy pro uživatele:

block alert
  div.alert.alert-warning.hidden

Hlavní obsah je v tomto bloku:

.content
  block content

Nakonec zápatí vypadá následovně:

block footer
  footer
    .container
      p
        | Copyright &copy; 2014 | Issues? Submit to a(href="https://github.com/azat-co/blog-express/issues") GitHub
        | .

Úplný kód layout.jade je následující:

doctype html
html
  head
    title= appTitle
    script(type="text/javascript", src="js/jquery-2.0.3.min.js")
    link(rel="stylesheet", href="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/css/bootstrap.min.css")
    link(rel="stylesheet", href="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/css/bootstrap-theme.min.css")
    link(rel="stylesheet", href="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/style.css")
    script(type="text/javascript", src="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/css/bootstrap-3.0.2/js/bootstrap.min.js")
    script(type="text/javascript", src="https://m03s6dh33i0jtc3uzfml36au-wpengine.netdna-ssl.com/js/blog.js")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
  body
    #wrap
      .container
        h1.page-header= appTitle
        p.lead Welcome to example from Express.js Experience by&nbsp;
          a(href="http://twitter.com/azat_co") @azat_co
          |. Please enjoy.
        block page
        block header
          div
            include includes/menu
        block alert
          div.alert.alert-warning.hidden
        .content
          block content
    block footer
      footer
        .container
          p
            | Copyright &copy; 2014 | Issues? Submit to
            a(href=" https://github.com/azat-co/blog-express/issues") GitHub
            | .

index.jade

Nyní se můžeme podívat na šablonu domovské stránky index.jade který rozšiřuje rozložení:

extends layout

Nastavíme menu proměnná na index , takže nabídka obsahuje (tj. menu.jade ) může určit, která karta se má zobrazit jako aktivní:

block page
  - var menu = 'index'

Hlavní obsah se seznamem článků, který pochází z locals je následující:

block content
  if (articles.length === 0)
    | There's no published content yet.
    a(href="/login") Log in
    | to post and publish.
  else
    each article, index in articles
      div
        h2
          a(href="/articles/#{article.slug}")= article.title

Úplný kód index.jade je následující:

extends layout

block page
  - var menu = 'index'
block content
  if (articles.length === 0)
    | There's no published content yet.
    a(href="/login") Log in
    | to post and publish.
  else
    each article, index in articles
      div
        h2
          a(href="/articles/#{article.slug}")= article.title

Obrázek 4–4 ukazuje, jak vypadá domovská stránka po přidání šablon stylů.

Obrázek 4–4. Domovská stránka

článek.jade

Stránka jednotlivých článků (obrázek 4–5) je relativně nenáročná, protože většina prvků je abstrahována do layout.jade :

extends layout

block content
  p
    h1= title
    p= text 

Obrázek 4–5. Stránka článku

login.jade

Podobně přihlašovací stránka obsahuje pouze formulář a tlačítko (s třídami/značkami Twitter Bootstrap):

extends layout

block page
  - var menu = 'login'

block content
  .col-md-4.col-md-offset-4
    h2 Log in
    div= error
    div
      form(action="/login", method="POST")
        p
          input.form-control(name="email", type="text", placeholder="[email protected]")
        p
          input.form-control(name="password", type="password", placeholder="***")
        p
          button.btn.btn-lg.btn-primary.btn-block(type="submit") Log in
        p
          input.form-control(name="password", type="password", placeholder="***")
        p
          button.btn.btn-lg.btn-primary.btn-block(type="submit") Log in

Obrázek 4–6 ukazuje, jak vypadá přihlašovací stránka.

Obrázek 4–6. Přihlašovací stránka

post.jade

Stránka příspěvku (obrázek 4–7) má jinou podobu. Tentokrát formulář obsahuje prvek textové oblasti:

extends layout
block page
  - var menu = 'post'
block content 
h2 Post an Article
div= error
div.col-md-8
  form(action="/post", method="POST", role="form")
    div.form-group
      label(for="title") Title
      input#title.form-control(name="title", type="text", placeholder="JavaScript is good")
    div.form-group
      label(for="slug") Slug
      input#slug.form-control(name="slug", type="text", placeholder="js-good")
      span.help-block This string will be used in the URL.
    div.form-group
      label(for="text") Text
      textarea#text.form-control(rows="5", name="text", placeholder="Text")
    p
      button.btn.btn-primary(type="submit") Save 

Obrázek 4–7. Stránka příspěvku

admin.jade

Administrátorská stránka (obrázek 4–8) obsahuje smyčku článků stejně jako domovská stránka. Kromě toho můžeme zahrnout front-end skript (js/admin.js ) specifické pro tuto stránku:

extends layout

block page
  - var menu = 'admin'

block content
  div.admin
    if (articles.length === 0 )
      p
        | Nothing to display. Add a new
        a(href="/post") article
        |.
    else

      table.table.table-stripped
        thead
          tr
            th(colspan="2") Actions
            th Post Title
        tbody
          each article, index in articles
            tr(data-id="#{article._id}", class=(!article.published)?'unpublished':'')
              td.action
                button.btn.btn-danger.btn-sm.remove(type="button")
                  span.glyphicon.glyphicon-remove(title="Remove")
              td.action
                button.btn.btn-default.btn-sm.publish(type="button")
                  span.glyphicon(class=(article.published)?"glyphicon-pause":"glyphicon-play",
title=(article.published)?"Unpublish":"Publish")
              td= article.title
      script(type="text/javascript", src="js/admin.js") 

Obrázek 4–8. Administrátorská stránka

K tisku ID článků jako atributů data-id používáme interpolaci :

tr(data-id="#{article._id}", class=(!article.published)?'unpublished':'')

A pro třídy a atributy titulků se používá podmíněný (ternární) operátor (https://github.com/donpark/hbs). Pamatujte, že je to JavaScript!

                  span.glyphicon(class=(article.published)?"glyphicon-pause":"glyphicon-play",
title=(article.published)?"Unpublish":"Publish") 

Shrnutí

Dozvěděli jste se o šablonách Jade a Handlebars (proměnné, iterace, podmínka, částečné znaky, escapování atd.) a jak je používat v samostatném skriptu Node.js nebo v Express.js. Kromě toho byly hlavní stránky blogu vytvořeny pomocí Jade.

V jiném tutoriálu jsme zkoumali důležitý aspekt moderního vývoje webu a softwarového inženýrství:vývoj řízený testy. Podívali jsme se na modul Mocha a napsali některé testy pro Blog ve skutečném stylu TDD/BDD.

Příklad s databází přidanou na Blog k naplnění těchto šablon je v ch5 na https://github.com/azat-co/practicalnode. Ukazuje vám, jak přeměnit Jade šablony na funkční HTML stránky!