2011-01-28 66 views
31

Có thể nhập một mô-đun Python vào một mẫu Jinja để tôi có thể sử dụng các chức năng của nó không? Ví dụ: Tôi có tệp format.py chứa phương pháp định dạng ngày và giờ. Trong một macro Jinja, tôi có thể làm điều gì đó như những điều sau đây không?Nhập khẩu một mô-đun Python vào một mẫu Jinja?

{% from 'dates/format.py' import timesince %} 

{% macro time(mytime) %} 
<a title="{{ mytime }}">{{ timesince(mytime) }}</a> 
{% endmacro %} 

format.py không phải là một mẫu, các mã trên mang lại cho tôi lỗi này:

UndefinedError: the template 'dates/format.py' (imported on line 2 in 'dates/macros.html') does not export the requested name 'timesince' 

... nhưng tôi đã tự hỏi nếu có một cách khác để đạt được điều này.

Trả lời

42

Trong mẫu, không, bạn không thể nhập mã python.

Cách để làm điều này là để đăng ký chức năng như một jinja2 custom filter, như thế này:

Trong file python của bạn:

from dates.format import timesince 

environment = jinja2.Environment(whatever) 
environment.filters['timesince'] = timesince 
# render template here 

Trong mẫu của bạn:

{% macro time(mytime) %} 
<a title="{{ mytime }}">{{ mytime|timesince }}</a> 
{% endmacro %} 
16

Just chuyển hàm vào mẫu, giống như vậy

from dates.format import timesince 
your_template.render(timesince) 

và trong mẫu, chỉ cần gọi nó giống như bất kỳ chức năng khác,

{% macro time(mytime) %} 
    <a title="{{ mytime }}">{{ timesince(mytime) }}</a> 
{% endmacro %} 

Chức năng là công dân hạng nhất trong python, vì vậy bạn có thể vượt qua họ xung quanh giống như bất cứ điều gì khác. Bạn thậm chí có thể vượt qua trong một mô-đun toàn bộ nếu bạn muốn.

2

Bạn có thể xuất tất cả các ký hiệu có sẵn trong mô-đun bằng cách cung cấp mô-đun __dict__ làm tham số cho phương thức hiển thị khuôn mẫu jinja. Sau đây sẽ làm cho các hàm sẵn có và các kiểu __builtin__, kiểm tra và loại mô-đun cho khuôn mẫu.

import __builtin__ 
import inspect 
import types 

env=RelEnvironment() 
template = env.get_template(templatefile) 

export_dict={} 
export_dict.update(__builtin__.__dict__) 
export_dict.update(types.__dict__) 
export_dict.update(inspect.__dict__) 

result=template.render(**export_dict) 

Trong mẫu, sử dụng một chức năng của các module xuất khẩu tương tự như sau:

{%- for element in getmembers(object) -%} 
{# Use the getmembers function from inspect module on an object #} 
{% endfor %} 
3

Mẫu không biết import, nhưng bạn có thể dạy nó với importlib:

import importlib 
my_template.render(imp0rt = importlib.import_module) # can't use 'import', because it's reserved 

(bạn cũng có thể đặt tên là "import" bằng cách chuyển đối số với dict)

kwargs = { 'import' : importlib.import_module } 
my_template.render(**kwargs) 

sau đó trong jinja-mẫu, bạn có thể nhập bất kỳ mô-đun:

{% set time = imp0rt('time') %} 
{{ time.time() }} 
Các vấn đề liên quan