--- title: เพิ่ม Netlify CMS ใน Hugo slug: netlify-cms-hugo author: LazyWasabi date: 2021-08-11T16:50:44+0700 lastmod: 2021-09-04T23:03:56+0700 images: - https://source.unsplash.com/-nz-GTuvyBw tags: - Hugo - Web Dev - Netlify CMS comments: host: mastodon.social username: lazywasabi id: "106738250669492570" --- [Netlify CMS](https://www.netlifycms.org/) คือตัวจัดการเนื้อหา (CMS - Content Management System) สำหรับเว็บไซต์ที่สร้างด้วย static site generator พัฒนาโดยทีม Netlify และเปิดเป็น[โอเพนซอร์ส](https://github.com/netlify/netlify-cms)ให้ทุกคนใช้ได้ฟรี [การทำงาน](https://github.com/netlify/netlify-cms#how-it-works)ของ Netlify CMS จะเชื่อมต่อกับ Git เพื่อดึงข้อมูลเนื้อหาของเว็บไซต์ และเมื่อเราสร้างหรือแก้ไขเนื้อหา ก็จะสร้าง commit ใหม่ใน repo ของเราให้อัตโนมัติ ถ้าสนใจลองใช้งานก่อนได้ที่[เว็บตัวอย่าง](https://cms-demo.netlify.com/)ครับ ## สร้างไฟล์ใน Hugo Netlify CMS ทำงานแบบ single page app และต้องการเพียงแค่ 2 ไฟล์เพื่อทำงานบนเว็บไซต์เรา ไฟล์แรกคือ `index.html` เป็น frontend ของตัว CMS และอีกไฟล์คือ `config.yml` สำหรับตั้งค่า CMS ใน Hugo เราจะสร้าง 2 ไฟล์นี้ขึ้นมาในโฟลเดอร์ `static/admin` แบบนี้ ``` static └ admin ├ index.html └ config.yml ``` โดยในไฟล์ `index.html` ให้วางโค้ดนี้ลงไป ```html Content Manager ``` ส่วนไฟล์ `config.yml` ตอนนี้ปล่อยว่างไว้ แล้วไปตั้งค่า backend กันก่อน ## ตั้งค่า backend Netlify CMS ทำงานโดยเชื่อมต่อกับ Git โดยรองรับทั้ง [GitHub](https://www.netlifycms.org/docs/github-backend/), [GitLab](https://www.netlifycms.org/docs/gitlab-backend/) และ [BitBucket](https://www.netlifycms.org/docs/bitbucket-backend/) โดยเราสามารถเลือกเชื่อมต่อกับบริการ Git ต่างๆ ได้โดยตรง หรือถ้าโฮสต์เว็บบน Netlify จะมีอีกทางเลือกคือใช้ [Netlify Git Gateway](https://docs.netlify.com/visitor-access/git-gateway/) ถ้าเลือกเชื่อมต่อกับบริการ Git โดยตรง เวลาล็อกอินเข้า CMS ก็ใช้บัญชีของบริการ Git นั้นๆ โดยสิ่งที่จำเป็นต้องมีคือ [OAuth server](https://github.com/netlify/netlify-cms/issues/663#issuecomment-335023723) ซึ่งถ้าโฮสต์เว็บบน Netlify จะ[มีให้ใช้](https://docs.netlify.com/visitor-access/oauth-provider-tokens/)อยู่แล้ว ข้อดีของวิธีนี้คือสามารถใช้ฟีเจอร์ [Open Authoring](https://www.netlifycms.org/docs/open-authoring/) (รองรับเฉพาะ GitHub) ที่เปิดให้ใครก็ตามที่มีบัญชี GitHub สามารถล็อกอินเข้า CMS ของเรา เพื่อ fork repo ไปแก้ไข และสร้าง pull request กลับมาได้ โดยทั้งหมดนี้สามารถทำผ่าน Netlify CMS ได้เลย อีกทางเลือกหนึ่งคือใช้ [Netlify Git Gateway](https://docs.netlify.com/visitor-access/git-gateway/) เป็นการเชื่อมต่อกับบริการ Git ผ่านเซิร์ฟเวอร์ Netlify (รองรับเฉพาะ GitHub และ GitLab) และใช้ [Netlify Identity](https://docs.netlify.com/visitor-access/identity/) ในการล็อกอินเข้า CMS ข้อดีของวิธีนี้คือ คนที่จะเข้าใช้งาน CMS ไม่จำเป็นต้องมีบัญชีของบริการ Git สามารถสร้างบัญชีผ่าน Netlify Identity แล้วล็อกอินเข้า CMS ได้เลย โดยในเว็บนี้ผมใช้วิธีเชื่อมต่อกับ GitHub โดยตรงเพราะ setup ง่ายกว่า และไม่ต้องเปิดใช้ Netlify Identity แต่ถ้าใครจะใช้ผ่าน Git Gateway สามารถทำตามขั้นตอนใน [docs ของ Netlify CMS](https://www.netlifycms.org/docs/add-to-your-site/#authentication) ได้เลยครับ ## สร้าง GitHub OAuth App และตั้งค่า OAuth Server สิ่งที่ต้องทำอย่างแรกคือสร้าง GitHub OAuth App เพื่อใช้ล็อกอินเข้า CMS โดยไปที่หน้าตั้งค่าบัญชีใน GitHub > Developer settings > OAuth Apps (หรือ[คลิกที่นี่](https://github.com/settings/developers)) แล้วคลิกสร้างแอปใหม่ ![สร้าง GitHub OAuth ใหม่](https://cdn.lazywasabi.net/blog/i/register-new-github-oauth-app.png) จากนั้นใส่ชื่อ เว็บไซต์ และรายละเอียดได้ตามต้องการ ส่วนในช่อง Authorization callback URL ให้ใส่เป็น `https://api.netlify.com/auth/done` คลิกปุ่มลงทะเบียน หลังจากนั้นคลิกสร้าง client secret ใหม่ แล้วนำ client ID และ client secret ที่ได้มาไปใส่ที่หน้าตั้งค่าใน Netlify ไปที่หน้าแดชบอร์ดของ Netlify > เลือกเว็บไซต์ > ​Site settings > Access control > OAuth และคลิกปุ่ม Install Provider เลือก GitHub และใส่ client ID และ client secret ที่ได้มาลงไป เท่านี้ก็เรียบร้อยครับ ![ติดตั้ง auth provider ใน Netlify](https://cdn.lazywasabi.net/blog/i/netlify-install-auth-provider.png) ## ตั้งค่า Netlify CMS ด้วยไฟล์ config.yml หลังจาก setup ระบบหลังบ้านที่จะเชื่อมกับ GitHub เรียบร้อย ต่อมาคือตั้งค่าตัว Netlify CMS ครับ ให้เรากลับมาที่ไฟล์ `config.yml` ที่สร้างไว้ในขั้นตอนแรก ### backend อันดับแรกคือกำหนด backend ก่อน ใครใช้ GitHub เหมือนผมก็ใช้โค้ดด้านล่างนี้ได้เลย และอย่าลืมเปลี่ยนช่อง `repo` กับ `branch` ให้ถูกต้องด้วยนะครับ ```yaml backend: name: github repo: lazywasabi/blog branch: main ``` ### โฟลเดอร์รูปภาพ Netlify CMS รองรับการอัปโหลดรูปภาพด้วย โดยเราต้องกำหนดโฟลเดอร์ที่จะใช้เก็บรูปภาพแบบนี้ ```yaml media_folder: 'static/images' public_folder: '/images' ``` - `media_folder`: คือโฟลเดอร์ที่เราต้องการใช้เก็บรูปภาพ ในตัวอย่างผมให้เก็บไว้ที่โฟลเดอร์ static/images - `public_folder`: ใช้ใน URL เพื่อแสดงรูปบนเว็บไซต์ ใน Hugo ง่ายๆ คือตัด static ออกไป ### Collections Collections ใน Netlify CMS คือการบอกตัว CMS ว่าเว็บเรามีเนื้อหาอะไรบ้าง หรือเทียบกับ [Sections](https://gohugo.io/content-management/sections/) ใน Hugo ยกตัวอย่างในเว็บไซต์ผมต้องสร้าง [2 collections](https://github.com/lazywasabi/blog/tree/main/content) คือ posts สำหรับบล็อก และ pages สำหรับหน้าเว็บปกติ นอกจากจะบอกว่ามีเนื้อหาอะไรบ้างแล้ว เรายังต้องระบุช่องข้อมูลต่างๆ ที่จะปรากฏใน UI ของ CMS สำหรับแต่ละ collection ด้วย โดยจะอิงจาก [front matter](https://gohugo.io/content-management/front-matter/) สมมติเนื้อหาในโฟลเดอร์ posts เราใช้ front matter แบบนี้ ```yaml --- title: 'เพิ่ม Netlify CMS ใน Hugo' slug: 'netlify-cms-hugo' draft: false date: 2021-08-11 tags: - first tag - second tag images: - https://cdn.lazywasabi.net/blog/i/image.jpg --- ``` โค้ดที่ต้องใช้จะหน้าตาประมาณนี้ ```yaml collections: - name: 'post' label: 'Post' folder: 'content/posts' create: true slug: '{{year}}-{{month}}-{{day}}-{{fields.slug}}' fields: - { label: 'Title', name: 'title', widget: 'string', required: true } - { label: 'Slug', name: 'slug', widget: 'string', required: true } - { label: 'Draft', name: 'draft', widget: 'boolean', required: false } - { label: 'Publish Date', name: 'date', widget: 'datetime', format: 'YYYY-MM-DDTHH:mm:ssZZ', required: true, } - { label: 'Image', name: 'images', widget: 'list', required: false, summary: '{{fields.image}}', field: { label: Image, name: image, widget: image }, } - { label: 'Tags', name: 'tags', widget: 'list', required: false } - { label: 'Content', name: 'body', widget: 'markdown', required: false } ``` - `name`: ใช้อ้างอิงในระบบ CMS ห้ามซ้ำกับ collection อื่น - `label`: ใช้แสดงใน UI ของ CMS - `folder`: โฟลเดอร์ที่เก็บไฟล์ของ collection นี้ - `create`: อนุญาตให้สร้างไฟล์ใหม่ใน collection นี้ไหม - `slug`: ชื่อไฟล์ที่จะสร้าง ถ้าตามโค้ดตัวอย่าง ชื่อไฟล์จะออกมาเป็น `2021-08-11-netlify-cms-hugo.`md สุดท้ายที่ดูยากหน่อยคือ `fields` ใช้สำหรับกำหนดช่องข้อมูลที่จะแสดงใน UI ของ CMS โดยอิงกับ front matter โดยแต่ละ fields สิ่งที่จะต้องมีคือ - `label`: สำหรับแสดงใน UI ของ CMS - `name`: สำหรับอ้างอิงกับ front matter - `required`: กำหนดว่า field นี้ต้องกรอกข้อมูลหรือไม่ ค่าเริ่มต้นคือ `true` ถ้า field ไหนที่ไม่จำเป็นให้ต้ังเป็น `false` - `widget`: สำหรับกำหนดรูปแบบของ field นั้นๆ ดู widget ทั้งหมดที่ใช้ได้[ที่นี่](https://www.netlifycms.org/docs/widgets/) โดยบาง widget ก็จะตั้งค่าเพิ่มเติมได้ ยกตัวอย่างจากโค้ดด้านบน - `title`: ใช้ `string` ซึ่งจะแสดงเป็นช่องข้อความปกติ - `date`: ใช้ `datetime` เป็นช่องสำหรับใส่วันที่และเวลา มีปฏิทินให้เลือก และตั้งค่ารูปแบบวันที่ เวลา และเขตเวลาได้ - `images`: ใน Hugo ใช้เป็น `list` และตั้งค่าให้ field ย่อยเป็น `image` สำหรับตัวอย่างการใช้งานจริง ลองดู[ไฟล์ config.yml ของเว็บไซต์ผม](https://github.com/lazywasabi/blog/blob/main/static/admin/config.yml) เทียบกับ front matter ของ[โพสต์นี้](https://raw.githubusercontent.com/lazywasabi/blog/main/content/posts/2021-08-11-netlify-cms-hugo.md)เป็นตัวอย่างได้ครับ หลังจากตั้งค่าเรียบร้อยแล้ว ลองเข้าใช้งาน CMS ดู โดยไปที่ `เว็บไซต์.com/admin/` ถ้าตั้งค่าทุกอย่างถูกต้อง ก็จะสามารถล็อกอิน และแก้ไขเนื้อหาของเว็บไซต์ได้แล้วครับ ## Editorial Workflow อีกหนึ่งฟีเจอร์สำคัญของ Netlify CMS คือ [Editorial Workflow](https://www.netlifycms.org/docs/configuration-options/#publish-mode) ให้เราสามารถสร้างฉบับร่าง และตรวจสอบเนื้อหาก่อนเผยแพร่ได้ เปิดใช้งานได้โดยเพิ่มโค้ดนี้ลงในไฟล์ตั้งค่า ```yaml publish_mode: editorial_workflow ``` หลังจากเปิดใช้งานแล้ว เมื่อเราสร้างหรือแก้ไขเนื้อหาผ่าน CMS แทนที่จะเป็นการ commit เข้า branch ที่เราตั้งไว้โดยตรง Netlify CMS จะสร้าง branch ใหม่แยกสำหรับแต่ละหน้าที่เราแก้ไข และสร้าง pull request ใหม่บน GitHub และในฝั่ง CMS ก็จะมีเมนู Workflow เพิ่มเข้ามา ในหน้านี้จะถูกแบ่งออกเป็น 3 ช่อง คือ Drafts, In Review และ Ready โดยหน้าที่สร้างใหม่หรือถูกแก้ไข จะมารออยู่ในช่อง Drafts ในระหว่างนี้เราสามารถแก้ไขหน้านี้ต่อได้ โดยจะเป็นการสร้าง commit ใหม่ใน branch และ pull request ของหน้านั้นๆ ![Editorial Workflow ใน Netlify CMS](https://cdn.lazywasabi.net/blog/i/netlify-cms-editorial-workflow.png) {.wide} และเมื่อพร้อมสำหรับการเผยแพร่ ก็ลากย้ายหน้านั้นให้มาอยู่ในช่อง Ready โดยหน้าที่อยู่ในสถานะ Ready เท่านั้นที่เราสามารถกดปุ่ม publish ได้ โดยเมื่อเรากด publish ก็จะเป็นการ merge pull request และลบ branch ของหน้านั้นทิ้งไป ## ตั้งค่าเพิ่มเติม Netlify CMS ยังรองรับการตั้งค่าเพิ่มเติมอีกหลายอย่าง เช่น [เปลี่ยนโลโก้ในหน้าล็อกอิน](https://www.netlifycms.org/docs/configuration-options/#custom-logo), [ปรับแต่ง CSS สำหรับหน้าพรีวิวใน editor](https://www.netlifycms.org/docs/customization/) หรือปรับแต่งให้ [editor ให้รองรับ shortcode ใน Hugo](https://www.netlifycms.org/docs/hugo/#using-hugo-shortcodes-in-the-markdown-editor) ดูข้อมูลเพิ่มเติมได้ที่ [docs ของ Netlify CMS](https://www.netlifycms.org/docs/intro/) เลยครับ อย่างของเว็บนี้ผมก็เพิ่มให้ editor รองรับ shortcode ที่ผมใช้ ลองดูโค้ดที่ผมใช้ได้ที่[ไฟล์นี้](https://github.com/lazywasabi/blog/blob/main/static/admin/cms.js) **อ่านต่อ:** [ล็อกอิน Netlify CMS ด้วย GitHub บน Vercel](/blog/netlify-cms-vercel/)