Blog tối thiểu chức năng (Minimum viable blog)
(ostwilkens.se)- Mục tiêu là xây dựng blog cá nhân dưới dạng trang tĩnh trên tên miền hiện có, đồng thời đáp ứng việc thêm nội dung và SEO cơ bản với mức triển khai tối thiểu
- Việc triển khai được đơn giản hóa thành một
template.htmlnhỏ,markdown2,render.pydo yêu cầu O1 tạo ra, và viết bài bằng Markdown - Mẫu sử dụng chỉ HTML/CSS cơ bản như
system-ui, chiều rộng tối đa70ch,color-scheme: light dark,viewport,UTF-8 render.pychuyển./posts/{post}/eng.mdthành HTML, điều chỉnh đường dẫn hình ảnh, rồi tạo./blog/{post}.htmlvàindex.html- Bài viết cho thấy có thể tạo một blog vận hành chỉ với render tĩnh và hosting, không cần Jekyll, Ghost hay WordPress
Yêu cầu cho blog tối thiểu và cấu hình thực tế
- Điểm khởi đầu là bốn yêu cầu
- Sử dụng tên miền đã sở hữu
- Tuân theo tiêu chuẩn web hiện đại và có SEO ở mức tốt
- Việc thêm nội dung mới phải thật dễ dàng
- Mọi trang đều được build tĩnh
- Luồng triển khai thực tế rất đơn giản
- Viết một
template.htmlnhỏ - Chạy
pip install markdown2 - Yêu cầu O1 tạo script
render.py - Viết bài, render rồi đưa lên hosting
- Viết một
- Không sử dụng các engine blog có sẵn như Jekyll, Ghost, WordPress
Mẫu và script render
template.htmlchỉ chứa cấu trúc tài liệu HTML cơ bản và CSS tối thiểu- Dùng
color-scheme: light darkđể chỉ định hệ màu sáng/tối - Kiểu nội dung chính được đặt là
system-ui,sans-serif, chiều rộng tối đa70ch, chiều cao dòng1.5, cỡ chữ1.25em - Sử dụng liên kết trang chủ có
id="head-link"và chỗ giữ{{ content }}
- Dùng
render.pydùngmarkdown2để chuyển bài viết Markdown thành HTML- Thư mục đầu vào là
./posts, thư mục đầu ra là./blog - Mỗi bài được đọc từ
./posts/{post_directory}/eng.md - Header
#đầu tiên được dùng làm tiêu đề bài viết - Markdown được chuyển với các tùy chọn
fenced-code-blocks,header-ids - Đường dẫn hình ảnh trong
<img src="được đổi theo chuẩn/posts/{post_code}/ {{ content }}trong template được thay bằng HTML đã chuyển đổi, và chuỗi tiêu đề cũng được thay bằng tiêu đề bài viết
- Thư mục đầu vào là
- Trang chỉ mục cũng được tạo trong cùng script đó
greetings.mdđược chuyển sang HTML trước- Đọc tiêu đề của từng bài rồi thêm danh sách liên kết
/blog/{post_code}.html - Kết quả cuối cùng được lưu thành
index.html
- Bài viết được viết thủ công vào 2025-03-31
5 bình luận
Hiện tại tôi cũng đang vận hành blog của mình đúng như ở trên. Tôi đã tự tạo một SSG đáp ứng các nhu cầu cá nhân của mình để sử dụng. Tôi còn thêm các tính năng tùy chỉnh riêng để tận dụng chức năng ảnh thumbnail, danh mục và thẻ. Các ảnh đính kèm được tự động chuyển đổi sang webp để tham chiếu, nhờ vậy tốc độ render khiến tôi rất hài lòng.
Ồ, vậy những tính năng tùy biến như thế anh/chị tự viết code để bổ sung dần dần à? Tôi cũng luôn định tự DIY, nhưng rồi lại chần chừ vì các tính năng mở rộng và plugin mà những framework blog SSG tôi đang dùng sẵn có cung cấp.
Nếu bớt tham một chút, thì phần còn lại thật ra không quá khó. Ngay cả
ssgcũng chỉ cần nhờ AI là nó viết hết code cho, và nếu bảo thêm tính năng thì thật sự nó cũng thêm được hết luôn hahaChỉ cần chọn một phông chữ đẹp thì nhìn cũng khá ổn.
Ý kiến trên Hacker News
Tôi nhớ đến biểu đồ trong bài blog này: https://molodtsov.me/2023/02/how-to-start-your-blog-in-2023/
Khi sa vào vũng lầy trình tạo site tĩnh (SSG), phần lớn thời gian lại dành để viết và mày mò về chính SSG, thay vì những bài vốn muốn viết hay những việc vốn muốn làm
Cuối cùng tôi bỏ SSG, cài WordPress rồi thôi không bận tâm nữa; cảm giác được giải phóng rất lớn
Nếu mục tiêu là mày mò rồi viết về quá trình đó thì ổn, và những người không bị việc mày mò cản trở viết lách cũng ổn, nhưng tôi thì không
Điều cuối cùng bạn cần đúng lúc định viết là một cái cớ để trì hoãn
WordPress và mọi plugin đều có thể bị xâm nhập nếu không được cập nhật, còn BDFL là người có thể chặn việc phân phối bản cập nhật bảo mật hoặc quyền truy cập để nhận chúng vì những lý do cá nhân vụn vặt
Site tĩnh không có lỗ hổng bảo mật cần vá, nên ngay cả khi một dự án SSG sụp đổ hoàn toàn vì vấn đề của người quản trị thì cũng không quá quan trọng; nhưng với WordPress thì điều đó trở nên rất quan trọng
Vì cần cách để khách truy cập để lại bình luận, tôi thêm Disqus, và rốt cuộc nó thành một mớ hỗn hợp gồm nhiều dịch vụ và rất nhiều JavaScript
Vài năm trước, để tự sở hữu dữ liệu của mình và không phụ thuộc vào dịch vụ bên ngoài nữa, tôi xuất các bình luận Disqus ra, mày mò Serendipity một thời gian rồi ổn định với WordPress
Tôi có thể nhập bình luận và các trang Markdown, và cũng có plugin phát hành mọi thứ lên Fediverse
Khi làm cho nó chạy bằng SQLite và bật tự động cập nhật, thực tế là gần như không cần bảo trì nữa
Nó đòi hỏi quá nhiều bảo trì vì những tính năng rất có thể bạn không cần. Nếu không giữ cập nhật, nó có thể trở thành một phần của botnet
Với hầu hết blog, trình tạo site tĩnh là đủ, và ngay cả khi cần bảo trì thì tôi có thể làm vào thời điểm mình muốn
Điều tôi thật sự muốn là một lệnh duy nhất để xuất bản và một cách dễ dàng kéo thả hình ảnh vào bài viết; cái trước hoạt động tốt, còn cái sau làm được nhờ tính năng xuất bản Jupyter Notebook
Điều tôi tuyệt đối không muốn là một kiểu mà việc “gửi HTML đến client” lại phải gánh thêm thứ như cơ sở dữ liệu
Hay đấy, nhưng để gọi là blog thì tôi cảm thấy cần thêm hai tính năng nhỏ nữa
Thứ nhất, phải sắp xếp bài viết theo ngày, bài mới nhất hiện trước, và hiển thị ngày ở đâu đó. Để giữ cấu hình tối thiểu, có thể dùng metadata của file bài viết, chẳng hạn thời điểm tạo
Thứ hai, tất nhiên là cần RSS feed. Chỉ với script hiện có và một template RSS tối thiểu, có vẻ dễ tạo một feed đơn giản chỉ chứa liên kết và tiêu đề
Việc được “theo dõi” không phải lúc nào cũng tốt, và có thể tạo áp lực phải chiều theo độc giả. Đó chính là yếu tố khiến mạng xã hội trở nên tệ hại
Với mục 1, tôi đang nghiêng về hướng tự động tạo một file chứa metadata bằng định dạng như TOML
Mục 2, RSS, chắc chắn tôi sẽ thêm, nhưng nó phụ thuộc vào mục 1 :-)
Tôi luôn thích các website độc lập, và website của tôi cũng bắt đầu theo cách tương tự khoảng 25 năm trước
Khi đó công nghệ phù hợp duy nhất mà tôi biết là Classic ASP, nên tôi làm thật đơn giản với cấu hình tối thiểu, chỉ bằng ASP
Hiện giờ site chạy dưới dạng site được tạo tĩnh bằng Common Lisp, và có vẻ cấu hình này sẽ là thiết lập lâu dài: https://github.com/susam/susam.net/blob/main/site.lisp
Bắt đầu bằng một tập hợp các trang đơn giản từng là cách hay để tạo một website khả dụng tối thiểu, nhưng theo thời gian tôi cần thêm các tính năng như RSS feed, danh sách blog theo ngày, chỉ mục theo tag, hỗ trợ nội dung không phải blog như công cụ/trò chơi/demo, và bình luận không dùng bên thứ ba
Mỗi khi yêu cầu tăng lên thì mã nguồn cũng phình ra, từ vài trăm dòng nay đã thành khoảng 1300 dòng Common Lisp
Dù vậy tôi vẫn muốn giữ nó ở mức có thể nắm toàn bộ mã trong đầu cùng lúc, và khi có lỗi thì có thể suy luận rồi sửa trong vòng 10 phút
Dạo này tôi bị cám dỗ muốn thêm blogroll cung cấp danh sách bài viết của các blogger tôi thích. Nó có thể thay thế trình đọc feed, nhưng tôi sẽ cẩn thận để nó không phình thành thứ đọc cả email
Mã nguồn ở đây: https://github.com/brilee/modern-descartes-v2/blob/master/ma...
Nó gồm RSS feed, danh sách blog theo ngày, hệ thống gắn tag, và server phát triển cục bộ có theo dõi file để biên dịch lại
Phiên bản hiện tại được giữ dưới dạng script Python dưới 1000 dòng: https://github.com/llimllib/obsidian_notes/blob/c93b9b5c46fe...
Tôi đã tạo các trang phát sinh như tập hợp bài viết, chỉ mục, slideshow, và cả các biến thể tag cho người và video game
Bạn cũng có thể kiểm soát hoàn toàn giao diện và cảm giác của các widget thông thường như thư viện thumbnail hay hộp trích dẫn
Nó có thể dùng làm tài liệu tham khảo ở mức khái quát
Sau này tôi có thể sẽ muốn nhúng shader và web game nữa, nhưng hy vọng độ phức tạp không tăng quá nhiều
Giá mà trình duyệt hỗ trợ native text/markdown và text/gemini thì tốt
Nếu trình duyệt có thể render PDF, thì việc thêm một formatter đơn giản cho nội dung Markdown/Gemini và stylesheet do người dùng tự chọn có lẽ cũng không khó đến thế
Hiện giờ vẫn có thể viết blog text/plain, nhưng nó không phải hypertext thực sự và bị thiệt về SEO. Có thể dùng link header để làm phép gì đó chăng
Hỗ trợ các định dạng khác sẽ hạ rào cản xuất bản gọn gàng và trả quyền kiểm soát về cho người dùng
Trước hết các trình duyệt phải thống nhất dùng biến thể và extension Markdown nào. Markdown gần như là CSV của thế giới định dạng văn bản, vì ai cũng dùng theo cách riêng
Nếu tối giản quá thì sẽ bị chê là vô dụng, còn nếu chọn extension thì sẽ bị chê là cồng kềnh
Ngay cả khi muốn thảo luận cẩn trọng về ưu nhược điểm ngắn hạn và dài hạn, có thể sẽ bị chặn bằng câu “đừng để sự hoàn hảo trở thành kẻ thù của điều tốt”
Dù có thống nhất được một tập tính năng cụ thể, tôi cũng nghi ngờ liệu nó có thật sự đáng không
Việc đọc PDF trực tiếp trong trình duyệt là đủ phổ biến, nhưng lợi ích của việc đọc Markdown trực tiếp có lẽ chỉ đến với một phần các nhà phát triển phần mềm trên thế giới và khoảng năm người kỳ quặc nào đó
Vì vậy nếu trong đời tôi không thấy trình duyệt render Markdown native thì cũng không ngạc nhiên
Cũng có thư viện cho XSLT để dùng khi cần phiên bản mới hơn hỗ trợ native của trình duyệt, và có thư viện cho nhiều định dạng như jpegxl nữa
Nếu là
html_content = html_content.replace('Minimum viable blog', title)thì mỗi khi chuỗiMinimum viable blogxuất hiện trong bài viết, nó sẽ bị đổi thành tiêu đề bài hiện tại à? Đúng là bug không?Đoạn code trong bài là bản nháp đầu tiên do O1 tạo, và chuỗi này đã được thay bằng
{{ title }}Tôi đã thử nghiệm blog tối giản khoảng 15 năm và học được vài mẹo
Chỉ cần kiểu như
const title = lines.match(/# (.+)/)[1]là đủ, nên có thể tránh frontmatterCác blog của tôi chưa bao giờ có nhiều bài đến mức cần phân trang, tag, category hay sắp xếp
JSX khá ổn như một bộ dựng chuỗi thuần server-side nếu dùng các hack đáng ngờ như https://immaculata.dev/guides/enabling-jsx.html
Giờ GitHub Pages cũng dễ dùng các bước build tùy ý thay cho Jekyll với những thứ như https://immaculata.dev/guides/using-gh-pages.html
highlight.js gần như là vua của việc tô sáng cú pháp code cực dễ, chỉ cần thêm ba dòng vào HTML; shiki thì đẹp nhưng chậm
Dùng các framework blog tĩnh tiêu chuẩn như Hugo/Zola + Cloudflare Pages thì dễ
Blog của tôi cũng là cấu hình tối giản dưới 100KB và đáp ứng tất cả các tiêu chí mà tác giả bài gốc liệt kê
Tôi dùng theme Hugo Blog Awesome, làm theo guideline 512kb và đã kiểm tra kích thước trang, loại bỏ ảnh cùng JS không cần thiết. Ngay từ đầu cũng không có nhiều
Tham khảo: https://512kb.club, https://radar.cloudflare.com/scan
Tôi từng vận hành “MVB” một thời gian, nhưng của tôi còn đơn giản hơn
Chỉ đặt một trang HTML, viết bài dưới dạng file
.txtvà cập nhật trang chủ thủ côngDù khá dài dòng, nhưng tôi vẫn thấy dễ hơn là đối phó với web hiện đại
Sau đó tôi chuyển sang hướng tinh vi hơn; hiện tôi dùng Astro cho trang cá nhân và blog, và nó thật sự tuyệt vời
Astro tuyên bố trên landing page rằng đây là nền tảng tốt nhất cho “site tập trung vào nội dung”, và sau 6 tháng dùng thử tôi đã đồng ý
Nó cung cấp các quy ước rõ ràng, dễ làm theo cho gần như mọi thứ cần thiết để tạo blog, đồng thời loại bỏ những phần thừa thãi
Tôi đã thử nghiệm cách dùng Bun JS và HTML trong chuỗi JavaScript trên một vài site
Bun có flag
—hotđể tạo lại HTML tĩnh khi có thay đổiIntelliJ IDE nhận diện chú thích
// language=htmlphía trên chuỗi, rồi format và highlight cú pháp HTML bên trongDùng hàm JavaScript thuần thay vì ngôn ngữ template giúp bạn tự viết logic cần thiết mà không phải tra xem làm điều đó trong ngôn ngữ template ra sao
Vì chán những website quá cồng kềnh khiến tải lâu, tôi cũng dùng một cách tiếp cận rất giống cho blog của mình: https://blog.borrego.dev
Mã nguồn: https://github.com/agubelu/blog