Sử dụng Jade templates với nodejs

Giới thiệu

Jade là một template engine cho Node.js, nó khá đơn giản và biên dịch thành HTML và cực kì hữu ích cho FE developer

jade-template-engine-nodejs-express-web-framework.png

Lấy cảm hứng từ HAML (một template engine cho Ruby on Rails), Jade ban đầu thiết kế ra chủ yếu để làm template engine phía server cho Node.js nhưng nó cũng có thể sử dụng để gõ XML,RSS và cũng triển khai được với php ,ruby, python, java..

JADE giúp chúng ta tạo ra những đoạn code HTML nhanh hơn, sạch hơn ,DRY hơn

Đối với Jade, mọi cú pháp viết html đã tinh giản hết, không còn phải đóng mở các thẻ (tag), không phải thêm các từ khóa cơ bản như: class, div, id..., các tag bọc lồng nhau đơn giản là dùng các khoảng trắng để thể hiện (thường người ta dùng tab cho dễ nhìn), đó là bạn thụt lề các tag này vào, ra là được. Để dễ hình dung, chúng ta nhìn vào ví dụ sau:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5)
  body
    h1 Jade - node template engine
    #container.col
      if youAreUsingJade
        p You are amazing
      else
        p Get on it!
      p.
        Jade is a terse and simple templating language with a
        strong focus on performance and powerful features.

Chuyển thành HTML sẽ như sau:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Jade</title>
    <script type="text/javascript">
      if (foo) bar(1 + 5)
    </script>
  </head>
  <body>
    <h1>Jade - node template engine</h1>
    <div id="container" class="col">
      <p>You are amazing</p>
      <p>Jade is a terse and simple templating language with a strong focus on performance and powerful features.</p>
    </div>
  </body>
</html>

Jade rất dễ sử dụng từ viết tag, chèn text, javascript, link, add thuộc tính, rồi đặt id, class đặc biệt thú vị đó là cho sử dụng vòng lặp, hằng biến, điều kiện cũng như dữ liệu từ bên ngoài. Chúng ta sẽ đi từ những ví dụ đơn giản, đến nâng cao nhé. Tạo một thư mục JadeEx, sau đó cài đặt module của jade bằng lệnh:

$node install jade

Tạo hai file sau:

template.jade: Là file jade mà chúng ta sẽ code jade vào đó

index.js: Là file mà chúng ta sẽ build ra html từ template là xuất ra trình duyệt.

Ở file index.js, nhiệm vụ là sử dụng jade module, đọc từ template ra và xuất ra html, chúng ta đơn giản chỉ dùng đoạn code sau:

 var jade = require('jade');
var html = jade.renderFile('template.jade');
var http = require("http");
http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/html;charset=utf-8"});
    response.write(html);
    response.end();
}).listen(8080);

Hiện tại file template chúng ta đang rỗng, nên chả in ra cái gì cả. Giờ bạn thử đoạn code sau vào file template nhé.

doctype html
html(lang='en')
  head
    title Jade
  body
    h1 Jade - node template engine

Kết quả xuất ra html sẽ là:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Jade</title>
  </head>
  <body>
    <h1>Jade - node template engine</h1>
  </body>
</html>

Chúng ta sẽ có các cách viết cho phần tag, class, text, id, javascript...lần lượt như sau:

Tạo tag đơn giản

div
  address
  i
  strong

utput sẽ là:

<div>
  <address></address><i></i><strong></strong>
</div>

Đưa text vào nội dung tag:

h1 Welcome to Jade
p
  | Text can be included in a number of
  | different ways.
p.
  This way is shortest if you need big
  blocks of text spanning multiple
  lines.

Out put là:

<h1>Welcome to Jade</h1>
<p>
  Text can be included in a number of
  different ways.
</p>
<p>
  This way is shortest if you need big
  blocks of text spanning multiple
  lines.
</p>

Chèn id, class và thuộc tính vào tag

h1#title Welcome to Jade
button.btn(data-action="bea") Awesome

Out put sẽ là:

<h1 id="title">Welcome to Jade</h1>
<button data-action="bea" class="btn">Awesome</button>

Thật là đơn giản phải không các bạn. Bây giờ là đến phần chèn dữ liệu động, và vòng lặp. Đến đây dữ liệu chúng ta put từ bên ngoài vào nên không render file thông thường nữa, mà chúng ta cần compile nó. Vậy nên cần thay đổi lại file index.js một chút.

var jade = require('jade');
var fs = require('fs');

var popularPosts = {posts :  [{id: 1,
                    title:"NodeJS là gì?"
                    },{
                        id: 2,
                        title:"Viết ứng dụng Hello World bằng NodeJS"
                    },{
                        id: 3,
                        title:"Sử dụng Jade trong NodeJS như thế nào?"
                    }]};

var jadetemplate = jade.compile(fs.readFileSync('template.jade', 'utf8'));
console.log(popularPosts.length);
var html = jadetemplate(popularPosts);
console.log(html);

Chúng ta có list các Bài viết Đọc nhiều, gồm 3 bài với id, tiêu đề. Giờ chúng ta cần xuất ra html list như sau:

  • NodeJS là gì?

  • Viết ứng dụng Hello World bằng NodeJS

  • Sử dụng Jade trong NodeJS như thế nào?

Để xuất ra dạng list trong html, ta dùng cặp thể <ul>, <li> thôi.

Ở file template.jade ta sử lại như sau:

ul
 - each post in posts
  li.item #{post.title}

Ở template, ta chú ý:

Dùng dấu - để bắt đầu một đoạn code giống javascript. Ở đây duyệt hết các post trong list post, với mỗi post, thì gán post.title vào thẻ li.

Ok, hiểu sơ lược vậy đã. Giờ ta chạy thử xem sao nào:

$npm index.js

Nếu output ra là:

<ul>
    <li class="item">NodeJS là gì?</li>
    <li class="item">Viết ứng dụng Hello World bằng NodeJS</li>
    <li class="item">Sử dụng Jade trong NodeJS như thế nào?</li>
</ul>

Là bạn đã thành công rồi đó.

Bây giờ chúng ta sẽ phát triển lên một tý.

Trường hợp bạn cần lồng các list con vào nữa thì sao? Ví dụ như list cây danh mục chẳng hạn.

  • Ngôn ngữ lập trình
    • NET
    • PHP
    • Java
  • Hệ cơ sở dữ liệu
    • MS SQL
    • MySQL
    • Oracle
  • Hệ điều hành
    • Windows
    • MAC OSX
    • Linux

Thì ta sẽ làm sao.

Hoàn toàn đơn giản, cú pháp template cũng như trên mà thôi.

ul.cate

 - each category in categories

  li.item #{category.name}

   ul.subcate

    - each subcate in category.listsubcates

     li.subitem #{subcate.name}

index.js ta truyền dữ liệu vào, và thay đổi một chút để xuất ra hml xem trên trình duyệt xem thế nào nhé.

var jade = require('jade');
var fs = require('fs');
var listCategory = {
    categories : [
                    {
                        id: 1,
                        name : "Ngôn ngữ lập trình",
                        listsubcates : [
                            {
                                id : 11,
                                name : ".NET"
                            },
                            {
                                id : 12,
                                name : "PHP"
                            },
                            {
                                id : 13,
                                name : "Java"
                            }
                        ]
                    },
                    {
                        id: 2,
                        name : "Hệ cơ sở dữ liệu",
                        listsubcates : [
                            {
                                id : 21,
                                name : "MS SQL Server"
                            },
                            {
                                id : 22,
                                name : "MySQL"
                            },
                            {
                                id : 23,
                                name : "Oracle"
                            }
                        ]
                    },
                    {
                        id: 3,
                        name : "Hệ điều hành",
                        listsubcates : [
                            {
                                id : 21,
                                name : "Windows"
                            },
                            {
                                id : 32,
                                name : "MAC OSX"
                            },
                            {
                                id : 33,
                                name : "Linux"
                            }
                        ]
                    }
                ]
};
var jadetemplate = jade.compile(fs.readFileSync('template.jade', 'utf8'));
var html = jadetemplate(listCategory);

var http = require("http");
http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/html;charset=utf-8"});
    response.write(html);
    response.end();
}).listen(8080);

Ok, chạy lệnh:

$node index.js

Mở trình duyệt lên và kiểm tra:

http://localhost:8080/

Kết quả như hình sau là bạn thành công rồi nhé:

jade_1.png

Giờ chúng ta thêm chút style cho nó nhé.

Thay đổi nội dung file template thành:

doctype html
html(lang='vn')
  head
    meta(charset='utf-8')
    title Danh sách chuyên mục
    link(href='http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css', rel='stylesheet')
    style(type='text/css').
      ul.cate{border: 1px solid #ACACAC;width: 200px;margin: auto;}
      li.item{font-weight: 700;font-size: 15px;}
      ul.subcate{font-style: italic;color: blue;}
  body
   ul.cate
    - each category in categories
      li.item #{category.name}
        ul.subcate
          - each subcate in category.listsubcates
            li.subitem #{subcate.name}
    script(src='http://code.jquery.com/jquery.js')

Chú ý có 3 thứ mới nhé:

  1. Chèn link file css bên ngoài. Mình sử dụng:
link(href='http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css', rel='stylesheet')
  1. Chèn link js bên ngoài:
script(src='http://code.jquery.com/jquery.js')
  1. Chèn style inner html:
style(type='text/css').
      ul.cate{border: 1px solid #ACACAC;width: 200px;margin: auto;}
      li.item{font-weight: 700;font-size: 15px;}
      ul.subcate{font-style: italic;color: blue;}

Ở 1,2 mình đưa vào để các bạn nắm được cách chèn thôi, chứ trong ví dụ ta cũng không dùng. Ở ví dụ là chèn đoạn style cho các ul, li của ta thêm chút xíu cho nó thay đổi thôi.

Giờ chạy lại xem kết quả thế nào nào.

jade_2.png

Oh, thay đổi style rồi nhé.

Html Output:

<!DOCTYPE html>
<html lang="vn">
<head>
    <meta charset="utf-8">
    <title>Danh sách chuyên mục</title>
    <link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
        ul.cate {
            border: 1px solid #ACACAC;
            width: 200px;
            margin: auto;
        }

        li.item {
            font-weight: 700;
            font-size: 15px;
        }

        ul.subcate {
            font-style: italic;
            color: blue;
        }
    </style>
</head>

<body>
    <ul class="cate">
        <li class="item">Ngôn ngữ lập trình
            <ul class="subcate">
                <li class="subitem">.NET</li>
                <li class="subitem">PHP</li>
                <li class="subitem">Java</li>
            </ul>
        </li>
        <li class="item">Hệ cơ sở dữ liệu
            <ul class="subcate">
                <li class="subitem">MS SQL Server</li>
                <li class="subitem">MySQL</li>
                <li class="subitem">Oracle</li>
            </ul>
        </li>
        <li class="item">Hệ điều hành
            <ul class="subcate">
                <li class="subitem">Windows</li>
                <li class="subitem">MAC OSX</li>
                <li class="subitem">Linux</li>
            </ul>
        </li>
        <script src="http://code.jquery.com/jquery.js"></script>
    </ul>
</body>
</html>

Một số điểm lưu ý:

  • Để thụt đầu dòng trong template các bạn có thể dùng space hoặc tab, tuy nhiên cần phải dùng đồng nhất và đều. Việc thụt không đúng sẽ dễ gây ra lỗi, cũng như các thẻ không lồng đúng vào nhau.

  • Ở dữ liệu JSON, các bạn chú ý phải đúng tên thuộc tính, đúng mảng hoặc list khi truyền sang file template.

Vậy để gen ra html động, với jade template engine trên nodejs cũng đơn giản phải không các bạn.

Kết luận

Việc bạn sử dụng jade để cắt giao diện thiết kế website chắc chắn nó sẽ tuyệt vời hơn HTML, thời gian tiết kiệm sẽ giúp bạn sáng tạo, sẽ có những website mà bạn sẽ tự hào khi bạn đã làm quen với code trên jade. Và sau đây chúng ta sẽ tóm tắt ưu nhược điểm ở jade nhé!

Ưu điểm:

  • Dễ tiếp cận, dễ sử dụng.

  • Gọn gàng, dễ đọc.

  • Có nhiều tính năng hay, giúp tăng tối đa tốc độ phát triển website.

Nhược diểm:

  • Tutorial không có nhiều, nên ban đầu sẽ mất một ít thời gian để làm quen.

  • Quá trình cài đặt hơi bối rối với những người mới làm quen.

Tham khảo:

http://jade-lang.com/

http://jade-lang.com/reference/doctype/

http://phpgatedaily.blogspot.com/2015/09/viet-html-nhanh-hon-voi-jade-e-thiet-ke.html