The @layout_config decorator comes from Pyramid Layout and allows
us to define and register a layout. In this case we’ve stacked 3
decorators, thus making 3 layouts, one for each template language.

Note

The first @layout_config doesn’t have a name and is thus
the layout that you will get if your view doesn’t specifically
choose which layout it wants.

Lines 21-24 illustrates the concept of keeping templates and the template
logic close together. All views need to show the project_title.
It’s part of the global look-and-feel main template. So we put this
logic on the layout, in one place as part of the global contract,
rather than having each view supply that data/logic.

Let’s next look at where this is used in the template for one of the
3 layouts. In this case, the Mako template at
demo/templates/layouts/layout.mako:

<title>${layout.project_title}, from Pylons Project</title>

Here we see an important concept and some important magic: the template
has a top-level variable layout available. This is an instance of
your layout class.

For the ZPT crowd, if you look at the master template in
demo/templates/layouts/layout.pt, you might notice something weird
at the top: there’s no metal:define-macro. Since Chameleon allows a
template to be a top-level macro, Pyramid Layout automatically binds
the entire template to the macro named main_template.

The first line is the one that opts the template into the layout. In
home.jinja2 that line looks like:

{%extendsmain_template%}

For both of these, main_template is inserted by Pyramid Layout,
via a Pyramid renderer global, into the template’s global namespace.
After that, it’s normal semantics for that template language.

Back to views.py. The view function grabs the LayoutManager,
which Pyramid Layout conveniently stashes on the request. The
LayoutManager‘s primary job is getting/setting the current layout.
Which, of course, we do in this function.

Our function then grabs the layout instance and manipulates some state
that is needed in the global look and feel. This, of course, could have been
done in our AppLayout class, but in some cases, different views have
different values for the headings.