I'd like to do something like below.

I have the following routes configured:

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

The following views:

@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 {...}

There is a base template '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>

Now in my views I'd like to inject the following content into the div with id "content":

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

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

How would I go about changing home_view and foo_view above so that they can inject their own templates (home.pt, foo.pt) into base.pt? Somehow I also need to transfer data such as ${user_id} into base.pt as well. I was playing around with the wrapper argument when defining my views, but couldn't figure out how it works.

有帮助吗?

解决方案

You can achieve this in several ways (see e.g. Using ZPT Macros in Pyramid or Chameleon documentation introduction).

In your simple case, I think this is the fastest way: first, change your base.pt file to:

<!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>

This defines a content slot of the Chameleon macro.

Your foo.pt could look like this:

<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>

Note the use-macro="load: base.pt line. home.pt should follow the same pattern. user_id and other template variables are available to the macro, so, for example, if you set user_id to USER, /foo will render:

<!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>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top