6 điểm bởi GN⁺ 2025-05-04 | 5 bình luận | Chia sẻ qua WhatsApp
  • 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.html nhỏ, markdown2, render.py do 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 đa 70ch, color-scheme: light dark, viewport, UTF-8
  • render.py chuyển ./posts/{post}/eng.md thành HTML, điều chỉnh đường dẫn hình ảnh, rồi tạo ./blog/{post}.htmlindex.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.html nhỏ
    • 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
  • Không sử dụng các engine blog có sẵn như Jekyll, Ghost, WordPress

Mẫu và script render

  • template.html chỉ 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 đa 70ch, chiều cao dòng 1.5, cỡ chữ 1.25em
    • Sử dụng liên kết trang chủ có id="head-link" và chỗ giữ {{ content }}
  • render.py dùng markdown2 để 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
  • 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

 
ifmkl 2025-05-07

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.

 
winterjung 2025-05-07

Ồ, 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.

 
ifmkl 2025-05-07

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ả ssg cũ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 haha

 
ndrgrd 2025-05-04

Chỉ cần chọn một phông chữ đẹp thì nhìn cũng khá ổn.

 
GN⁺ 2025-05-04
Ý 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 năm 2025 có cùng lúc hai đặc tính nguy hiểm
      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
    • Tôi cũng tương tự. Từ lâu tôi bắt đầu với DokuWiki, rồi quyết định thử GitHub Pages; sau khi chuyển hết sang đó, tôi cần tìm kiếm nên gắn Google Custom Search vào
      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
    • Spam blog à? :) URL là https://rakhim.org/honestly-undefined/19/
    • Tôi đồng ý, nhưng cho rằng trong 95% trường hợp WordPress là quá mức cần thiết
      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
    • Tôi khá hài lòng với nikola: https://getnikola.com/
      Đ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 đề

    • RSS thì tốt, nhưng tôi nghĩ không nên là điều kiện bắt buộc để được công nhận là blog
      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
    • Hợp lý
      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

    • Tôi đã đi gần như cùng một con đường
      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
    • Con đường của tôi cũng tương tự, thực ra tôi đã lặp lại vài lần
      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...
    • Chính xác là vậy. Khả năng quyết định “tôi muốn tạo thiết bị này” rồi tự code nó tốt hơn bất kỳ WYSIWYG nào
      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
    • Tôi đã làm tính năng Flock trong Lamb, tức là syndicate feed vào blog của tôi. Tôi chủ yếu làm nó như một lựa chọn thay thế theo kiểu đa người dùng: https://github.com/svandragt/lamb
      Nó có thể dùng làm tài liệu tham khảo ở mức khái quát
    • RSS và ngày tháng thì chắc chắn có vẻ cần thiế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/markdowntext/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

    • Render Markdown native trong trình duyệt thì đáng tiếc là có vẻ ít khả năng xảy ra
      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
    • Việc render PDF trong trình duyệt được làm bằng JavaScript, hoặc ít nhất từng là như vậy
      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
    • Gemini cũng có định dạng riêng à?
  • Nếu là html_content = html_content.replace('Minimum viable blog', title) thì mỗi khi chuỗi Minimum viable blog xuấ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?

    • Đúng, bắt tốt lắm
      Đ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 frontmatter
    Cá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 .txt và cập nhật trang chủ thủ công
    Dù 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

    • Astro thật sự rất ấn tượng. Không hiểu sao nó chưa phổ biến hơn
    • Tò mò là bạn dùng theme của người khác hay tự làm
  • 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 đổi
    IntelliJ IDE nhận diện chú thích // language=html phía trên chuỗi, rồi format và highlight cú pháp HTML bên trong
    Dù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

    • Rất thích và trông đẹp. Trên mobile thì hiển thị thế nào?