Kiến trúc module RichText + Media Library

📅 January 23, 2026
Kiến trúc module RichText + Media Library

A. Data model (gợi ý) media_assets id (bigint) user_id / tenant_id (nếu đa user) original_name mime_type size_bytes width, height, duration (nullable) storage_disk (local/s3/b2) storage_path (path thật) public_url (url dùng hiển thị) checksum (sha256) để chống trùng created_at content_posts id title content_html hoặc content_json (Editor.js blocks / Quill delta) content_text (plain text để search) created_at, updated_at Gợi ý: nếu bạn muốn lâu dài + dễ migrate editor: lưu JSON (blocks/delta) và render ra HTML khi hiển thị. 

banner-hoi-dong-tham-dinh-1732083222094.webp

2) “RichText tự code” gồm những phần nào? A. Editor UI (frontend) Bạn có 3 hướng: contenteditable + toolbar tự làm Nhanh cho basic (bold/italic/link) Nhưng mệt: undo/redo ổn định, paste từ Word/Google Docs, list/table/code, selection bug… Editor.js (block-based) + bạn tự render + upload Hợp kiểu Notion, quản lý block rõ ràng Quill (classic WYSIWYG) Dễ dùng, output đẹp, MIT => Thực tế: đừng tự viết editor engine, hãy tự viết module + media library.

3) Media Library riêng kiểu WordPress A. API endpoints (PHP) POST /admin/media/upload (multipart) GET /admin/media/list?page=1&q=... POST /admin/media/delete?id=... POST /admin/media/rename POST /admin/media/folder/create (nếu muốn folder) POST /admin/media/attach (link media vào post) B. Chức năng nên có Upload ảnh/video/file Tạo thumbnail (ảnh) Detect mime thật (không tin extension) Giới hạn size, whitelist mime Hash file để tránh upload trùng CDN URL / signed URL (nếu private) Reuse file (dùng lại 1 asset cho nhiều bài) C. Storage Local: storage/media/YYYY/MM/uuid.ext Public serve qua Nginx alias Hoặc S3/B2: lưu storage_path + public_url

← Back to Blog