模板
Starlette 并非严格与任何特定的模板引擎耦合,但 Jinja2 是一个极好的选择。
Jinja2 模板
签名: Jinja2Templates(directory, context_processors=None, **env_options)
directory
- 一个字符串、os.Pathlike 或一个字符串或 os.Pathlike 的列表,表示一个目录路径。context_processors
- 一系列返回字典以添加到模板上下文的函数的列表。**env_options
- 传递给 Jinja2 环境的其他关键字参数。
Starlette 提供了一种简单的方法来进行 jinja2
配置。这可能是您默认想要使用的。
from starlette.applications import Starlette
from starlette.routing import Route, Mount
from starlette.templating import Jinja2Templates
from starlette.staticfiles import StaticFiles
templates = Jinja2Templates(directory='templates')
async def homepage(request):
return templates.TemplateResponse(request, 'index.html')
routes = [
Route('/', endpoint=homepage),
Mount('/static', StaticFiles(directory='static'), name='static')
]
app = Starlette(debug=True, routes=routes)
请注意,传入的 request
实例必须作为模板上下文的一部分包含在内。
Jinja2 模板上下文将自动包含一个 url_for
函数,因此我们可以在应用程序内正确地超链接到其他页面。
例如,我们可以从我们的 HTML 模板内部链接到静态文件:
<link href="{{ url_for('static', path='/css/bootstrap.min.css') }}" rel="stylesheet" />
如果您想要使用自定义过滤器,您将需要更新 Jinja2Templates
的 env
属性:
from commonmark import commonmark
from starlette.templating import Jinja2Templates
def marked_filter(text):
return commonmark(text)
templates = Jinja2Templates(directory='templates')
templates.env.filters['marked'] = marked_filter
使用自定义的 jinja2.Environment 实例
Starlette 也接受一个预先配置的 jinja2.Environment
实例。
import jinja2
from starlette.templating import Jinja2Templates
env = jinja2.Environment(...)
templates = Jinja2Templates(env=env)
上下文处理器
上下文处理器是一个函数,它返回一个字典以合并到模板上下文中。每个函数仅接受一个参数 request
,并且必须返回一个要添加到上下文中的字典。
模板处理器的一个常见用例是使用共享变量扩展模板上下文。
import typing
from starlette.requests import Request
def app_context(request: Request) -> typing.Dict[str, typing.Any]:
return {'app': request.app}
注册上下文模板
将上下文处理器传递给 Jinja2Templates
类的 context_processors
参数。
import typing
from starlette.requests import Request
from starlette.templating import Jinja2Templates
def app_context(request: Request) -> typing.Dict[str, typing.Any]:
return {'app': request.app}
templates = Jinja2Templates(
directory='templates', context_processors=[app_context]
)
!!! 信息 作为上下文处理器的异步函数不受支持。
测试模板响应
在使用测试客户端时,模板响应包括 .template
和 .context
属性。
from starlette.testclient import TestClient
def test_homepage():
client = TestClient(app)
response = client.get("/")
assert response.status_code == 200
assert response.template.name == 'index.html'
assert "request" in response.context
定制 Jinja2 环境
Jinja2Templates
接受 Jinja2 Environment
支持的所有选项。这将允许对 Starlette 创建的 Environment
实例进行更多控制。
对于 Environment
可用的选项列表,您可以在此处查看 Jinja2 文档
from starlette.templating import Jinja2Templates
templates = Jinja2Templates(directory='templates', autoescape=False, auto_reload=True)
异步模板渲染
Jinja2 支持异步模板渲染,然而一般来说,我们建议您使您的模板避免包含调用数据库查找或其他 I/O 操作的逻辑。
相反,我们建议您确保您的端点执行所有的 I/O,例如,在视图内严格评估任何数据库查询,并将最终结果包含在上下文中。