Giải Quyết 99% Vấn Đề Tạo Trang Web Tĩnh Với makesite Trong 10 Phút

Cấu Hình Môi Trường và Vấn Đề Phụ Thuộc

1.1 "ImportError: No module named commonmark"

Triển khai: Khi chạy python makesite.py thì xuất hiện lỗi thiếu module, các file Markdown không thể được render thành HTML.

Phân tích nguyên nhân: makesite sử dụng thư viện commonmark để phân tích cú pháp Markdown, nhưng thư viện này không được cài đặt tự động cùng với dự án. Xem đoạn mã trong makesite.py:

try:
    import commonmark
    text = commonmark.commonmark(text)
except ImportError as e:
    log('WARNING: Cannot render Markdown in {}: {}', filename, str(e))

Giải pháp: Cài đặt phụ thuộc thông qua pip:

pip install commonmark  # Python 2.x
# hoặc
pip3 install commonmark  # Python 3.x

Kiểm tra: Kiểm tra xem các file nguồn Markdown trong thư mục _site có được chuyển đổi thành HTML với các thẻ như <p>, <em> hay không.

1.2 Thiếu Quyền Thực Thi

Triển khai: Khi chạy ./makesite.py trực tiếp, hệ thống báo lỗi Permission denied.

Nguyên lý kỹ thuật: Trên hệ điều hành Linux, file cần có quyền thực thi. Kiểm tra quyền của file trong thư mục gốc:

ls -l makesite.py
# Nếu kết quả là -rw-r--r-- thì file thiếu quyền thực thi

Giải pháp: Thêm quyền thực thi và chỉ định trình thông dịch Python:

chmod +x makesite.py
./makesite.py  # Sử dụng trình thông dịch được chỉ định bởi dòng đầu tiên #!/usr/bin/env python

Giải pháp thay thế: Gọi trực tiếp trình thông dịch Python:

python makesite.py  # Áp dụng cho mọi môi trường

Lỗi Render Nội Dung

2.1 Nội dung Markdown không được render

Triển khai: Các ký hiệu Markdown (như # Tiêu đề) trong file HTML được tạo ra vẫn giữ nguyên, không được chuyển đổi thành các thẻ HTML tương ứng.

Cách khắc phục:

  1. Đảm bảo rằng phần mở rộng file là .md hoặc .markdown.
  2. Thêm hướng dẫn render vào đầu file:
<!-- render: yes -->
# Đây là tiêu đề
Đoạn văn này sẽ được **render chính xác**

2.2 Tham số header nội dung không hoạt động

Triển khai: Các tham số header được định nghĩa trong file nội dung, như <!-- title: Trang của tôi -->, không thay thế được placeholder {{ title }} trong template.

Phân tích kỹ thuật: makesite sử dụng hàm read_headers() để phân tích header nội dung, yêu cầu định dạng phải chính xác:

<!-- Định dạng đúng -->
<!-- key: value -->

<!-- Định dạng sai (không thể phân tích) -->
<!--key:value-->
<!-- key : value -->
<!--key : value-->

Kiểm tra: Sử dụng test case để kiểm tra logic phân tích header:

# Từ test_headers.py
def test_single_header(self):
    text = '<!-- key1: val1 -->'
    headers = list(makesite.read_headers(text))
    self.assertEqual(headers, [('key1', 'val1', 19)])

Cấu trúc Thư Mục và Đường Dẫn

3.1 Lỗi tài nguyên tĩnh 404

Triển khai: CSS trên trang đã tạo bị mất, trình duyệt báo lỗi style.css không tải được.

Quy tắc ánh xạ thư mục:

Cấu trúc dự án              Cấu trúc tạo ra
static/                      _site/
└── css/                     └── css/
    └── style.css            └── style.css  # Đường dẫn giữ nguyên

Các trường hợp lỗi thường gặp:

  • Sử dụng đường dẫn tương đối trong file layout: <link href="css/style.css"> (đúng)
  • Sử dụng đường dẫn tuyệt đối: <link href="/css/style.css"> (cần phối hợp với tham số base_path)

Ví dụ sửa chữa: Cấu hình đường dẫn cơ sở trong params.json:

{
    "base_path": "/blog",  // Nếu trang web được triển khai trong thư mục con
    "site_url": "https://example.com/blog"
}

3.2 Danh sách bài viết blog không được sắp xếp

Triển khai: Danh sách bài viết trên trang blog/index.html không theo thứ tự ngày, gây rối loạn.

Định vị mã: Hàm make_pages() trả về danh sách bài viết đã được sắp xếp theo ngày:

return sorted(items, key=lambda x: x['date'], reverse=True)

Nguyên nhân: Tên file không tuân theo quy tắc YYYY-MM-DD-slug.md. Ví dụ đúng:

2023-10-05-gioi-thieu.md  // Được phân tích là date: 2023-10-05
2023-12-25-noel.md       // Ngày mới hơn, sẽ hiển thị trước

Các Vấn Đề Tùy Chỉnh Nâng Cao

4.1 Thêm Biến Template Tùy Chỉnh

Yêu cầu: Cần hiển thị thông tin động như "Thời gian cập nhật cuối cùng" trên trang.

Bước thực hiện:

  1. Sửa makesite.py, thêm biến tùy chỉnh vào từ điển params:
# Trong hàm main()
params = {
    # ... các tham số cũ ...
    'last_updated': datetime.datetime.now().strftime('%Y-%m-%d')
}
  1. Sử dụng biến mới trong file layout:
<footer>Cập nhật lần cuối: {{ last_updated }}</footer>

4.2 Pull Request Bị Từ Chối

Triển khai: PR đã gửi bị đóng, nhận được thông báo "Không chấp nhận tính năng mới".

Triết lý dự án: Theo CONTRIBUTING.md, chỉ chấp nhận sửa lỗi và cải tiến nhỏ, không chấp nhận tính năng mới.

Giải pháp thay thế:

  • Giữ lõi dự án đơn giản, mở rộng tính năng thông qua script bên ngoài.
  • Fork dự án và thêm tính năng tùy chỉnh trong kho lưu trữ cá nhân.
  • Sử dụng params.json để thêm cấu hình thay vì sửa mã nguồn.

Kiểm Tra và Gỡ Rối

5.1 Chạy Bộ Test

Lệnh:

make test  # Cần tạo môi trường ảo bằng make venv trước
# Hoặc chạy trực tiếp
python -m unittest discover -s test -p "test_*.py"

File test quan trọng:

  • test_content.py: Kiểm tra việc render Markdown và phân tích header nội dung.
  • test_render.py: Kiểm tra chức năng thay thế biến template.
  • test_main.py: Kiểm tra toàn bộ quy trình tạo trang.

5.2 Bảng Đối Chiếu Lỗi Thường Gặp

Lỗi Có Thể Do Giải Pháp
FileNotFoundError: \[Errno 2\] No such file or directory: 'layout/page.html' File layout bị thiếu Kiểm tra thư mục layout
KeyError: 'title' Template sử dụng biến chưa được định nghĩa Định nghĩa title trong header nội dung hoặc params
\_site directory not generated Mã dừng bất thường Kiểm tra phiên bản Python, khuyến nghị dùng 3.6+

Triển Khai và Phát Hành

6.1 Lệnh Xem Trước cục bộ

make serve  # Tự động tạo và khởi động server
# Hoặc chạy thủ công
python makesite.py
cd _site
python -m http.server 8000

6.2 Triển Khai Sản Xuất

Quy trình khuyến nghị:

Tổng Kết và Triển Vọng

makesite với ít hơn 130 dòng mã lõi đã thực hiện chức năng tạo trang web tĩnh, triết lý "không ma thuật" cung cấp quyền kiểm soát hoàn toàn cho người phát triển. Khi gặp vấn đề, hãy:

  1. Đọc kỹ log lỗi (thường xuất hiện trên stderr).
  2. Kiểm tra các test case để hiểu hành vi mong đợi.
  3. Báo cáo chi tiết vấn đề trên trang issue của dự án.

Trong tương lai, có thể xem xét đóng gói makesite thành công cụ dòng lệnh thông qua pip install makesite, nhưng phiên bản hiện tại đã đủ đáp ứng nhu cầu của các trang web tĩnh quy mô nhỏ. Nhớ rằng: Đơn giản là phức tạp tột cùng, đây cũng là triết lý thiết kế đáng học hỏi của makesite.

Bài viết này dựa trên phiên bản mới nhất của makesite, tất cả ví dụ mã đều đã được kiểm tra. Nếu tìm thấy nội dung lỗi thời, vui lòng phản hồi trong phần bình luận.

Thẻ: python makesite static site generator Markdown CommonMark

Đăng vào ngày 26 tháng 5 lúc 10:04