Make Your Own Script Appender In Mako Templates

Loading

In a recently started Pylons project, I wanted to make an easy script appending facility in Mako templates.

The requirement:

  • base.mako contains the layout of the web page. Many templates inherit base.mako. Here's a snippet from base.mako
    <html>
    <head>
        <title>Some title</title>
        <script>...</script>
        <script>...</script>
    </head>
     
    </%def>
  • my_page.mako inherits base.mako. From within my_page.mako we want to be able to append script tags in the head section of the web page.

base.mako

# -*- coding: utf-8 -*-
<%! scripts = [] %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <title>${self.title()}</title>
    ${self.head_scripts()}
</head>
<body>
     ${self.menu()}
     ${next.body()}
     ${self.footer()}
</body>
</html>
...
<%def name="head_scripts()">
<% 
    all_scripts = []
    t = self
    while t:
      all_scripts = getattr(t.module, 'scripts', []) + all_scripts
      t = t.inherits
%>
% for script in all_scripts:
    <script src="${script}" type="text/javascript"></script>
% endfor

Notice the top portion of the template. We define a list variable called scripts. At this point scripts is empty.

<%! scripts = [] %>

We render the script tags by calling the function head_scripts().

 ${self.head_scripts()}

my_page.mako

<%inherit file="/base.mako"/>
 
<%! scripts = ['some_script.js'] %>

In my_page.mako, we define the variable scripts that contains the URLs. scripts is a list which lets you add any number of scripts to be appended.

<%! scripts = ['one.js', 'two.js', 'three.js'] %>

Looking back at base.mako, we have the function head_scripts() that grabs the scripts attribute in the inheritance chain . Once we have the list of all the URLs to be appended, we simply iterate and write the script tags.

<% 
    all_scripts = []
    t = self
    while t:
      all_scripts = getattr(t.module, 'scripts', []) + all_scripts
      t = t.inherits
%>
% for script in all_scripts:
    <script src="${script}" type="text/javascript"></script>
% endfor

getattr() ensures that if any template in the chain doesn't define scripts, there will be no error.

Once base.mako is setup, you can append the script tags by just defining a list in the inheriting templates. You can use the same technique to append title, link, style and other HTML tags.

About the author

Sudheer is an entrepreneur and software developer. Get more from Sudheer on Twitter.


Nice!

Thanks for the pointer. Saved me a lot of pain trying to get my template inheritance set up properly.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>. The supported tag styles are: <foo>, [foo].

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.