1

I am a newbie to pyramid and using pyramid with Chameleon. Can someone help me how to have a common template for header and footer and a layout which includes them.Couldn’t able to figure out exactly how to use wrapper. The Re-usable Template Macros also didn’t help much. Finally got this add on pyramid-layouts which seems to be promising but lacks in documentation.

Update

For Including header and footer as sepearte template file Mako and jinja2 have built-in ways but like me if you like chameleon style we have to use macros

  • Chameleon: Macros - Visit //chameleon.readthedocs.org/en/latest/reference.html#macros-metal
  • Jinja2: Templates - Visit //jinja.pocoo.org/docs/templates/#import
  • Mako: Inheritance - Visit //docs.makotemplates.org/en/latest/inheritance.html
Vinoth Kumar
  • 1,347
  • 1
  • 14
  • 23
  • Did you know that you can change the template engine? you can use jinja2 or mako if you want. – llazzaro Sep 25 '13 at 19:18
  • @llazzaro Thanks for your response :) , I am aware I can switch the template engines. Will jinja2 or mako provides option to embed or include template files? Earlier in php frameworks I used require_once() like function to include html files. I wish to know how to accomplish the same with pyramid – Vinoth Kumar Sep 25 '13 at 19:40
  • jinja2 for sure will allow you to use a base layout. mako I think it will also allow this. I asked you this since I had been in the same issue before and I finally switched to other template engine (can't remeber which one!). – llazzaro Sep 25 '13 at 20:45
  • @llazzaro Yes I agree, thanks for your inputs both jijnja2 and mako provides including templates from another file. Which is exactly I'm looking for :) – Vinoth Kumar Sep 26 '13 at 09:39
  • I found this blog post [jinja2 vs chameleon](http://www.brettdangerfield.com/post/jinja2_vs_chameleon) which will be very useful – Vinoth Kumar Sep 26 '13 at 20:05

2 Answers2

3

Since Chameleon 2.7.0 there is support for load: TALES expression, so it is possible to load the macros template directly from another template. For details see @sverbois answer or this related question: How to use template inheritance with chameleon?

Another, older approach described in Re-usable Template Macros tutorial, involves creating a class which contains the templates which need to bre references and passing an instance of the class into the view:

    class Layouts(object):

        @reify
        def global_macros(self):
            renderer = get_renderer("templates/macros.pt")
            return renderer.implementation().macros
  • Then you need to pass that Layouts thingie into your views. In the tutorial they did that by subsclassing the view class from Layouts:

    from layouts import Layouts
    class ProjectorViews(Layouts):
        ...
    
  • but you could as well just instantiate it and pass it directly:

    def blah(context, request):
        layouts = Layouts()
    
        return {
            (whatever data you want to pass to your template)
            layouts=layouts,
        }
    
  • In your macros template you use metal:define-macro to, well, define a macro:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:metal="http://xml.zope.org/namespaces/metal"
          xmlns:tal="http://xml.zope.org/namespaces/tal">
    
        <metal:company_menu define-macro="company_menu">
            <h1>Hi there!</h1>
        </metal:company_menu>
    
    </html>
    
  • To insert the macro into your other template, just use

    <div metal:use-macro="view.global_macros['company_menu']"></div>
    

(if you use a view class subclassed from Layouts as they proposed), or

    <div metal:use-macro="layout.global_macros['company_menu']"></div>

(if you instantiated the Layout object in a function-based view as I've shown in step 2 above)

Once that's working have a look at metal:define-slot and metal:fill-slot which will allow you to fill... err... slots in a macro with content supplied from the parent template

Community
  • 1
  • 1
Sergey
  • 11,892
  • 2
  • 41
  • 52
  • Thanks for your answer,I will give it a try. But I think it will be lot easier and maintainable to have a built-in way of loading one template from another as in Jinja2 and Mako. – Vinoth Kumar Sep 26 '13 at 09:38
1

You can simply have a "main.pt" like this

<!DOCTYPE html>
<html>
<head>
    ...
</head>
<body>
<div class="header">
    My global header
</div>
<metal:block define-slot="content" />
<div class="footer">
    My global footer
</div>
</body>
</html>

and use it in your view template "my_view_template.pt" like this

<html metal:use-macro="load: main.pt">

<div metal:fill-slot="content">
    <p>Hello !!!</p>
</div>

</html>
sverbois
  • 19
  • 1