Cách tải mẫu jinja trực tiếp từ hệ thống tệp


85

Các tài liệu jinja API tại pocoo.org trạng thái:

Cách đơn giản nhất để định cấu hình Jinja2 để tải các mẫu cho ứng dụng của bạn trông giống như sau:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
Điều này sẽ tạo ra một môi trường mẫu có cài đặt mặc định và một bộ nạp rằng ngoại hình lên các mẫu trong các mẫu thư mục bên trong yourapplication gói python.

Hóa ra, điều này không đơn giản như vậy vì bạn phải tạo / cài đặt một gói python với các mẫu của bạn trong đó, điều này gây ra rất nhiều sự phức tạp không cần thiết, đặc biệt nếu bạn không có ý định phân phối mã của mình. Bạn có thể tham khảo các câu hỏi SO về chủ đề tại đâyđây , nhưng câu trả lời rất mơ hồ và không thỏa mãn.

Điều mà một người mới ngây thơ muốn làm, rõ ràng là chỉ tải mẫu trực tiếp từ hệ thống tệp, không phải như một tài nguyên trong một gói. Làm thế nào là điều này được thực hiện?

Câu trả lời:


124

Đây là cách thực hiện : sử dụng a FileSystemLoaderthay vì a PackageLoader. Tôi tìm thấy các ví dụ trên web ở đâyở đây . Giả sử bạn có một tệp python trong cùng một tệp với mẫu của bạn:

./index.py
./template.html

Index.py này sẽ tìm thấy mẫu và hiển thị nó:

#!/usr/bin/python
import jinja2

templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "template.html"
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render()  # this is where to put args to the template renderer

print(outputText)

Hóa ra, tài liệu API jinja2 có một phần thảo luận về tất cả các bộ tải tích hợp , vì vậy thật đáng xấu hổ khi không nhận ra điều đó ngay lập tức. Nhưng phần giới thiệu được viết như vậy PackageLoaderdường như là phương pháp mặc định, "đơn giản nhất". Đối với những người mới làm quen với trăn, điều này có thể dẫn đến một cuộc rượt đuổi ngỗng hoang.


94
Thật nực cười khi bạn không thể tải một mẫu từ một tệp trong một dòng, ví dụjinja2.load_template('template.html')
Matt

4
Tôi luôn luôn có một Wrapper mà tôi chỉ cần gọi Jinja2 trong các ứng dụng của tôi, nơi tôi đặt tất cả tính cách rườm rà này, sau đó gọi nó như:Jinja2.render(template_name, data)
Seraf

11
Rủi ro bảo mật quan trọng! Bạn gần như chắc chắn muốn gọi jinja2.Environment(loader=templateLoader, autoescape=True). Hoặc xem tài liệu api để biết thêm thông tin. Chỉ cần phát hiện ra tôi đã kết thúc với một lỗ hổng XSS lớn từ sau câu trả lời này: /
andrewdotn

Cả hai liên kết ở trên cùng đều bị hỏng.
sshow

76

Một cách đơn giản hơn là gọi trực tiếp hàm jinj2.Templatetạo và sử dụng openđể tải tệp:

from jinja2 import Template
with open('template.html.jinja2') as file_:
    template = Template(file_.read())
template.render(name='John')

1
Thật không may, điều này không cho phép thiết lập bộ lọc tùy chỉnh. Việc tải mẫu tạo ra lỗi trong quá trình khởi chạy vì bộ lọc tùy chỉnh chưa tồn tại. Và theo cách này, bạn chỉ có quyền truy cập vào môi trường (bao gồm bộ lọc) sau khi khởi tạo.
Ronan Paixão

17

Đây là một lớp lót:

template = Template(open('template_file.j2').read())

Sau đó, bạn có thể hiển thị mẫu trên một dòng khác hoặc cho tất cả trong một dòng:

rendered = Template(open('template_file.j2').read()).render(var="TEXT")

1
Đáng buồn là điều này sẽ bị phá vỡ nếu có kế thừa mẫu, vì Jinja sẽ không thể tìm thấy các mẫu được tham chiếu.
Bemmu

3
Nhưng may mắn thay, điều này là đơn giản và đủ nếu bạn không sử dụng kế thừa, và chỉ không thể gửi một số email đơn giản chẳng hạn .. :)
smido

2

Nếu sử dụng Python 3.4+ và Jinja2 - v2.11 + - chúng ta có thể kết hợp đường dẫn của python và Hệ thống tệp để đơn giản hóa quy trình

from pathlib import Path
...

p = Path(__file__).parent.parent / 'templates' # sample relative path
env = Environment(
    loader=FileSystemLoader(Path(p)))
template = env.get_template('your_file.jinja2')

Tôi không thoải mái với việc sử dụng trực tiếp Template(file)vì xử lý kế thừa mẫu của Jinja có thể không hoạt động tốt.

Hỗ trợ Pathlib chỉ được thêm vào phiên bản mới nhất của Jinja - v2.11 +

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.