如何在Jinja模板有多个块时构建请求处理程序?
我想做一个简单的网站,使用的是GAE框架/服务。这个网站很小,我其实不需要功能强大的Django框架,所以我选择了谷歌自己做的Webapp2框架,搭配Jinja2模板语言。
我之前主要用的是很基础的PHP和HTML,所以现在要适应真正的框架工作方式有点困难。我现在最大的疑问是,模板系统和请求处理器是如何协同工作的,特别是当页面的模板有几个“动态”元素时。
我先解释一下我在PHP中是怎么做的,这样你可能更容易理解我想实现的目标。
假设我想要一个网站,里面有:
- 一个根据访问的页面而变化的标题,比如:“Mysite.com | 控制面板”
- 一个动态的菜单栏,可能会根据用户的个人资料或登录状态而变化
- 当然,页面的主体内容完全依赖于正在查看的页面
在PHP中,我会这样做,下面是一个简单的例子,index.php
:
<?php
/*here use the $_GET or $_POST variable, and the $_SESSION variable
to figure out who's connected, which page is being displayed,
and store those values in global variables, for the
included modules to use */
include('page_header.php'); // renders the whole <head> </head> tag and its content
echo "<body>";
include('views/menu.php'); //generates the menu, displays it
switch($page_name){
case "home":
include('home.php'); //renders the page body for the homepage
break;
case "articles":
include('home.php'); //renders the page body for the blog articles listing
break;
case "guestbook":
include('home.php'); //renders the page body for the guestbook
break;
}
echo "</body>";
每个包含的模块都会使用调用它们的脚本(index.php)中的变量,以及$_POST、$_GET、$_SESSION这些超级全局变量,来决定显示什么内容,并将其渲染成HTML。在这里,index.php
也做了一些非常基础的路由,使用了switch语句。
现在,回到webapp2和jinja2框架:
我明白,要用Jinja以模块化的方式构建网页,需要使用块结构,并且要extend
这些块。因此,为了构建一个类似于之前PHP例子的页面,我做了以下模板base.html
:
<html>
<head>
<link rel="stylesheet" href="/static/css/reset.css">
{% block title %}
{% endblock title %}
</head>
<body>
<div class="menu">
{% block menu %}
{% endblock menu %}
</div>
<div class="body">
{% block content %}
{% endblock content %}
</div>
</body>
</html>
我不明白的是,如何构建不同的处理器,这些处理器又会生成Jinja用来渲染块的上下文,并且避免冗余。
**另外,我可以使用多个不同的模板文件,它们单独只扩展一个块吗(例如:menu.html、header.html、body_home.html、body_articles.html等)**
你可以参考这个例子,这是一个小例子,几乎教会了我所有我需要知道的东西。
感谢任何提供的帮助,抱歉语法错误,英语不是我的母语。
1 个回答
在 jinja2
中有个叫做 宏 的功能,简单来说就是可以带参数的包含。
如果你需要带参数的包含,可以这样做:
{% macro menu(params) -%}
do something
{%- endmacro %}
然后在你的模板中调用这个宏:
<div> menu('bar') </dib>
如果不需要提供参数,那就直接在父模板中写静态的 HTML 就可以了。
关于处理程序,你可以参考 App Engine 的 hello world 示例,只需用你的链接来加载 jinja 的环境。
我知道你想把 php
的例子翻译过来,但尽量把逻辑放在处理程序中,而不是模板里。
至于你的第二个问题,是的,如果你想的话,可以只扩展一个块,如果需要父模板的内容,可以用 {{super()}}
来获取。