Skip to content
This repository has been archived by the owner on Feb 7, 2020. It is now read-only.

Template Inheritance

botanicus edited this page Sep 13, 2010 · 17 revisions

This page is up to date for Rango 0.1.

Template inheritance is simple, but very powerful concept of handling base template/child template. It’s way more powerful than the standard layout/view, because you can inherit in a chain, like base.htmladmin/base.htmladmin/posts.html, so you can have one site-wide base template and one for each subsites (usually admin & user part) which will inherit from the generic base template.

Basic Example

base.html.haml

!!! 1.0 Strict
%html{html_attrs("en")}
  %head
    / Title block with default value. If you don't redefine this block
    / in your child templates, it will be "My Cool E-shop", otherwise
    / it will be the value you provided in your child template
    %title= block(:title, "My Cool E-shop")
    %meta{name: "description", content: block(:description, Shop.company.description)}
    %meta{name: "keywords", content: block(:keywords, Shop.company.keywords)}
    = pupu :blueprint, plugins: ["fancy-type"]
    = pupu :mootools, more: true
  %body
    .container
      %h1= block(:title)
      = block(:content)
      %h3 Menu
      = block(:navigation)

eshop/base.html.haml

- extends "base.html"

- block(:navigation) do
  %ul
    %li
      %a{href: "/contact"} Contact
    %li
      %a{href: "/products"} Products

eshop/index.html.haml

- extends "eshop/base.html"

/ head
- block(:title, "Our Products")
- block(:description, "Just a list of our products")

/ content
- block(:content) do
  %h1 Test
  = partial "eshop/products/list"
  = paginate

Extending Existing Block Definition

It would be nice to have something like super() call for extending existing blogs, is it? Well, it’s actually easy:

= block(:head) do
  / what you want to put before
  = block(:head)
  / what you want ot put after

Arguments via Template Inheritance

Great thing is that block method can returns whichever value, not just a string. So if you want to pass just names of your JS files in your templates, just do:

/ base.html
= javascripts "application", *block(:javascripts, Array.new)
- extends "base.html"
- block(:javascripts, "mootools-core", "mootools-more")

Rango with AJAX

It has very nice usage with AJAX, you can do extends "base.html" unless request.ajax?, so if the request is AJAX, it renders just the child template, so you can just replace this part of page through your JavaScripts.

In real world it’s very common to have two requests: request which serve the whole page for users without JavaScript and fragment of page served through AJAX for users with JavaScript. In most of frameworks you need to create more templates. Not in Rango. See this template:

- extends "base.html" unless request.ajax?
- block(:head) do
  = pupu :flash
= block(:content) do
  %h1 The Page

When we get normal request, we extends base.html with content of head and content blocks. But if we got AJAX request, we don’t extend anything, we just render the template above. Important nuance here is that we have used - block(:head), but = block(:content). The first case just runs, but it isn’t placed to the template as the second one. And that’s it!

Links

- Template inheritance explanation at DjangoProject.com