เวลาอ่านด้วย hook
สิ่งที่จะได้
ตัวเลข "อ่านกี่นาที" ที่ CMS คำนวณทุกครั้งที่บันทึก ผู้แก้เห็นได้แต่แก้ไม่ได้ ใช้: hooks, สิทธิ์ระดับ field
1. Field
ts
{
name: 'readingTime',
type: 'number',
label: { en: 'Reading time (min)', th: 'เวลาอ่าน (นาที)' },
position: 'sidebar',
// อ่านอย่างเดียวทั้งในหน้า admin และ API ส่วน hook ด้านล่างเป็นคนตั้งค่า
access: { update: () => false },
}สิทธิ์ระดับ field กรองเฉพาะสิ่งที่คนส่งมา hook ยังตั้งค่าได้
2. Hook
bash
npm install @easy-cms/richtextbash
pnpm add @easy-cms/richtextbash
yarn add @easy-cms/richtextbash
bun add @easy-cms/richtextts
import { richTextToPlainText } from '@easy-cms/richtext'
const WORDS_PER_MINUTE = 200
function minutes(body: unknown): number {
const words = richTextToPlainText(body as never).split(/\s+/).filter(Boolean).length
return Math.max(1, Math.round(words / WORDS_PER_MINUTE))
}
// ใน collection posts:
hooks: {
beforeChange: [
({ data }) => (data.body === undefined ? data : { ...data, readingTime: minutes(data.body) }),
],
},ตอน update ที่ไม่ได้แก้ body จะไม่มี data.body ค่าเดิมจึงยังอยู่
ภาษาไทย
ภาษาไทยไม่เว้นวรรคระหว่างคำ การนับคำจากช่องว่างจึงได้ตัวเลขน้อยเกินไป ให้นับตัวอักษรแทน ภาษาไทยอ่านได้ประมาณ 800–1,000 ตัวอักษรต่อนาที: Math.round(richTextToPlainText(body).length / 900)
3. เติมค่าให้บทความเดิม
hook ทำงานตอนบันทึก บทความที่มีอยู่แล้วต้องบันทึกใหม่หนึ่งครั้ง:
ts
const cms = await getEasyCMS(config) // หรือ useEasyCMS() ใน Nuxt
const { docs } = await cms.find('posts', { limit: 0, draft: true, depth: 0 })
for (const post of docs) await cms.update('posts', post.id, { body: post.body })