Node.js初學筆記10: 在express-handlebars中輕鬆建立客製helper(handlebars custom helpers)

前言

一篇筆記中我們了解到要如何利用if & each 兩個helper去幫助我們做出動態的樣板,雖然很方便卻無法滿足我們所有的需求,畢竟if helper不能做更複雜的條件判斷,這時候就輪到客製helper(custom helper)出手了!

在介紹用法之前先試想一下一個情境,今天你在做一個記帳的程式,每一筆紀錄包含著以下的資訊

  • 消費項目名稱
  • 消費金額
  • 消費日期
  • 消費類別(假設是食、衣、住、行)

為了在頁面上呈現消費紀錄,你從資料庫抓資料出來並利用each將每一筆資料印出,一切都很順利,你做出類似這樣的效果。

現在問題出現了,光看項目名稱你看不出消費的類別,而你又不想傻傻的在頁面上直接寫個"類別:食",你希望在每筆消費旁邊增加對應的圖案,很明顯你學到的兩個helper幫不上忙,只好自己寫一個囉!

客製helper(custom helper)

官方文件中也有提到如何客製想要的helper,我個人認為那個做法有些不直觀,所以我後來找了另一種我比較喜歡的做法,可以達成一模一樣的效果。

首先回到app.js,我們修改一下設定樣板引擎(view engine)的部份。

app.js

//加入粗體字的部分
app.engine('handlebars', exphbs({
  defaultLayout: 'main', 
  helpers: {
    add_up: function (a, b) {
      return a + b
    }
  }
}))
app.set('view engine', 'handlebars') 

還記得我們一開始設置樣板時,我們利用了handlebars其中一個option:defaultLayout 去告訴它說我們預設的主頁面是main.handlebars嗎? helpers其實也是眾多option之一,你可以在這邊用你習慣的方式設立helper function,我這邊簡單寫了一個addUp 函數來做示範。

接著回到樣板的位置,我們測試一下剛建立的addUp是否正常運作。

views/index.handlebars

/*
.........
some codes here
.........
*/
<h1>{{add_up 5 9}}</h1> 

再次打開頁面你應該就會看到下方出現了數字14。

這邊有幾個重點需要注意一下。

  • 客製的helper不需要#開頭以及/結尾可直接使用
    當然你仍可以用一般的helper方式,並在中間夾入你要的HTML結構
    以addUp為例:
    {{#addUp}}
    {{this}}
    {{/addUp}}
  • 傳入的arguments用空格隔開而非一般的逗號

了解用法後我們就可以回頭解決我們的問題了,由於解決的邏輯不是本篇的重點,這邊就只提供程式碼跟粗略的說明,圖示部分使用了fontawesome做出預期的效果。

app.js

// 增加取得圖示的helper
app.engine('handlebars', exphbs({
  defaultLayout: 'main', helpers: {
    getImage: function (category, category_image) {
      return category_image[category]
    },
    add_up: function (a, b) {
      return a + b
    }
  }
})) 
 
app.get('/', (req, res) => {
  //建立圖示物件
  const category_image = {
    '食': '<i class="fas fa-utensils"></i>',
    '衣': '<i class="fas fa-tshirt"></i>',
    '住': '<i class="fas fa-home"></i>',
    '行': '<i class="fas fa-bus"></i>',
    '其他': '<i class="fas fa-shopping-bag"></i>'
  }
  //建立測試用的消費紀錄
  const records = [
    { name: "生鮮食品", amount: 1200, date: '2019-04-14', category: '食' },
    { name: "婚禮西裝", amount: 1800, date: '2019-04-15', category: '衣' },
    { name: "線上學費", amount: 3000, date: '2019-04-13', category: '其他' }
  ]
  //將消費紀錄與圖示物件傳入樣板中
  res.render('index', { records, category_image })
}) 

views/index.handlebars

<ul>
{{#each records}}
  //注意這邊傳入的兩個arugment,由於現在是在each的迴圈中 直接使用 category_image會報錯(畢竟在records中並沒有category_image) 
  {{{getImage this.category ../category_image}}}
   <li>
     {{this.name}}
     {{this.date}}
     金額:{{this.amount}}元
     Delete
     Edit
   </li>
 {{/each}}
</ul>

一切順利的話你會看到以下的成品~一切都如我們預期的美好:D。

結語

這篇文章中我們介紹了設立以及使用客製helper,舉的例子只是使用的其中一種情況!因應你開發的項目不同可以有更多不同的應用。當然你也可以使用官方的做法,同樣的東西你會寫成類似下方的東西。

const Handlebars = require('handlebars') 
Handlebars.registerHelper('addUp', function (options) {
  return options.fn(this) + 5
}); 

我想你可以理解為什麼我偏好文章中的方法了吧:P~!

本文章的程式碼可以在這裡取得,歡迎自由使用。

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s