将多个视图渲染的内容注入到Pyramid的一个基础模板中

2 投票
1 回答
942 浏览
提问于 2025-04-17 13:04

我想做一些类似下面的事情。

我已经配置了以下的路由:

config.add_route('home', '/')
config.add_route('foo', '/foo')

还有以下的视图:

@view_config(route_name='home', renderer='templates/home.pt')
def home_view(request):
    return {...}

@view_config(route_name='foo', renderer='templates/foo.pt')
def foo_view(request):
    return {...}

这里有一个基础模板 'templates/base.pt':

<!DOCTYPE html>
<html>
<head></head>
<body>
    Welcome ${user_id}<br>
    <a href="/foo">Foo</a><br>
    <div id="content">
        <!-- Inject rendered content here from either / or /foo --> 
    </div>
</body>
</html>

现在在我的视图中,我想把一些内容放进id为 "content" 的div里:

<!-- templates/home.pt -->
<div id="home-content">Home content</div>

<!-- templates/foo.pt -->
<div id="foo-content">Foo content</div>

我该如何修改上面的 home_viewfoo_view,让它们可以把自己的模板(home.pt, foo.pt)放进 base.pt 里呢?另外,我还需要把像 ${user_id} 这样的数据也传到 base.pt 里。我试着在定义视图时使用 wrapper 参数,但没搞明白它是怎么工作的。

1 个回答

3

你可以通过几种方式来实现这个功能(比如可以参考在Pyramid中使用ZPT宏或者Chameleon文档介绍)。

在你简单的案例中,我觉得最快的方法是:首先,把你的base.pt文件改成:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:tal="http://xml.zope.org/namespaces/tal"
      xmlns:metal="http://xml.zope.org/namespaces/metal">
<head></head>
<body>
    Welcome ${user_id}<br>
    <a href="/foo">Foo</a><br>
    <div id="content">
        <tal:block metal:define-slot="content">
        </tal:block>
    </div>
</body>
</html>

这段代码定义了Chameleon宏的一个content插槽。

你的foo.pt可以这样写:

<metal:main
    xmlns:tal="http://xml.zope.org/namespaces/tal"
    xmlns:metal="http://xml.zope.org/namespaces/metal"
    use-macro="load: base.pt">
    <tal:block metal:fill-slot="content">
        <div id="foo-content">Foo content</div>
    </tal:block>
</metal:main>

注意use-macro="load: base.pt"这一行。home.pt也应该遵循同样的模式。user_id和其他模板变量可以在宏中使用,所以,比如说,如果你把user_id设置为USER,那么/foo将会渲染出:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
    Welcome USER<br>
    <a href="/foo">Foo</a><br>
    <div id="content">
        <div id="foo-content">Foo content</div>
    </div>
</body>
</html>

撰写回答