contentful 是一個內容管理的服務,提供了 RESTful API、友善的編輯介面、排程發佈、Webhooks…等功能,並且提供了一個免費空間(有上限)。如有更進階的需要可付費購買,收費方式是每月依購買的方案收取指定的費用。
contentful 網站 https://www.contentful.com/
註冊頁 https://www.contentful.com/sign-up/
可使用 Github、Google 帳號登入或直接填表單進行註冊
建立方案的第一個步驟選擇類型,如未填寫付款資訊就不能選擇需付費的方案
這邊就直接選擇 Free 的方案,上面也會清楚標示可用上限之資訊
步驟二就是給 Space 一個名字,並選擇建立一個空的 space
步驟三確認後 Space 就建立完成
點選畫面上方的 Content model 功能,新增 content type
相當於建立一個資料表的欄位名稱與型態
一個 content type 最多可定義50個欄位,資料型態也有11種
每種資料型態都會有一些限制,可能是長度、數字最大最小值、日期時間格式…等等
詳細規格可以直接參考 Content data model,裡面有非常詳細的說明
新增欄位時,介面提供以下幾種欄位型態
欄位全部設定完成後,按下畫面右側 Save 即可開始依照剛剛的欄位設定建立資料內容
目前 blog 文章的欄位規畫一共有6個欄位,如下圖所示
主要的文章內容儲存於 Article Content 欄位,內容格式使用 markdown 所以欄位型態選擇 Long Text 即可
文章分類標籤儲存於 Category List 欄位,由於可能有多個分類,所以在設定時要特別勾選是多筆。
使用此方式的好處是後續在使用 api 時,可以直接使用參數的方式過濾資料,因此可節省資料傳輸的大小。如果使用 Json object 方式儲存,則需要將所有資料撈回再過濾。
如下圖所示紅框部份要勾選
點選畫面上方的 Content 功能,新增指定 content type 的資料內容
新增資料內容頁面會依據先前建立的 content type 呈現表單
編輯過程中會自動存檔
不同欄位型態會呈現不同輸入方式(日期選單、markdown 編輯器),也有基本檢核(例如長度、必填)
完成編輯後可選擇排程或是立即 Publish
點選畫面上方的 Settings 選擇 API keys 開啟設定畫面,按下 "Add API key"
編輯完成後按下 Save 即完成設定
畫面上有3個不可編輯的欄位,由系統自動產生的資訊,分別是
後續在專案中呼叫 contentful api 時,需要用到 Space ID 與 access token,其中 Content Delivery API - access token 是用來取得正式發佈的資料,而 Content Preview API - access toke 除了取得正式發佈的資料還有也會取得狀態為 "Draft"的資料。方便你在開發環境使用,可快速切換。
執行下列指令安裝 contentful 套件
npm install contentful --save
在 plugins 資料夾新增一個檔案 contentful.js 用來建立呼叫 contentful api 的 client
建立時必需提供 space id 與 access token
如果有切換環境的需要,則可設定 environment 屬性,此設定預設值為 master
// plugins/contentful.js
const contentful = require('contentful')
// use default environment config for convenience
// these will be set via `env` property in nuxt.config.js
const config = {
space: process.env.CTF_SPACE_ID,
accessToken: process.env.CTF_CDA_ACCESS_TOKEN
}
// export `createClient` to use it in page components
module.exports = {
createClient () {
return contentful.createClient(config)
}
}
在 nuxt.config.js 設定環境變數 CTF_SPACE_ID、CTF_CDA_ACCESS_TOKEN 與 CTF_BLOG_POST_TYPE_ID,供程式中取用
// ./nuxt.config.js
const config = require('./config')
module.exports = {
// ...
env: {
CTF_SPACE_ID: config.CTF_SPACE_ID,
CTF_CDA_ACCESS_TOKEN: config.CTF_CDA_ACCESS_TOKEN,
CTF_BLOG_POST_TYPE_ID: config.CTF_BLOG_POST_TYPE_ID
}
// ...
}
利用 plugins/contentful.js 的 createClient 方法建立呼叫 api 的物件使用 getEntries 進行 api 呼叫
以下為簡易的呼叫 api 範例
import contentful from '~/plugins/contentful.js'
const client = contentful.createClient()
const getArticles = () => {
return client.getEntries({
// 設定要取得的 content type id
content_type: config.CTF_BLOG_POST_TYPE_ID,
// 指定呼叫 api 回傳的欄位有那些
select: 'fields.id,fields.createDate,fields.title,fields.slug,fields.categoryList',
// 指定回傳資料排序的欄位與排序方式(由大至小 or 由小至大)
order: '-fields.createDate'
})
.then(res => map(res.items, item => item.fields))
.catch(() => Promise.resolve([]))
}
完成以上步驟之後即可在 Nuxt.js 專案內呼叫 contentful 的 api
為了方便維護與管理我在專案中建立 services/api.js,並且於檔案內建立需使用的呼叫 api 方法提供程式使用
在 Content 新增的資料稱為 Entry,而 getEntries 則是用來取得這些 Content 資料的方法,回傳為 Promise 物件
getEntries 方法提供了非常多的參數可供開發人員設定使用,以下針對目前專案有使用的參數進行說明
其他詳細的使用方式也可參考官方文件,點擊參數說明內的"Query entries"可看到該參數使用的程式碼(可選平台)並且模擬查詢(參數可自行調整)
import contentful from '~/plugins/contentful.js'
const client = contentful.createClient()
client.getEntries({
content_type: 'post',
select: 'fields.id,fields.createDate,fields.title,fields.slug,fields.categoryList',
order: '-fields.createDate',
limit: 10
})
import contentful from '~/plugins/contentful.js'
const client = contentful.createClient()
client.getEntries({
content_type: 'post',
select: 'fields.id,fields.createDate,fields.title,fields.slug,fields.categoryList',
order: '-fields.createDate',
'fields.categoryList': 'Nuxt.js'
})
import contentful from '~/plugins/contentful.js'
const client = contentful.createClient()
client.getEntries({
content_type: 'post',
'fields.id': 'a-series-of-nuxtjs-01'
})
contentful
contentful Guides
contentful Content data model
contentful API reference
contentful.js - Contentful JavaScript Delivery SDK
Integrate Contentful with Nuxt.js