扫描特定属性的后代模板命名空间

时间:2013-12-11 23:05:00

标签: python templates mako

我正在尝试理解用于访问Mako中的后代属性的Version One - Use Namespace.attr示例。我在 page.html 中有基页模板, index.html 中的索引页继承了 page.html 。我想允许 page.html (和继承它的页面)指定要包含的Javascript和CSS文件,并允许page.html处理它们。

page.html中

<!DOCTYPE html>
<%namespace name="common" file="common.html"/>
<%

# Scan for scripts and styles to include.
include_scripts = []
include_styles = []
for ns in context.namespaces.values():
    if hasattr(ns.attr, 'include_scripts'):
        include_scripts.extend(ns.attr.include_scripts)
    if hasattr(ns.attr, 'include_styles'):
        include_styles.extend(ns.attr.include_styles)

%>
<html>
  <head>
   <title>${self.attr.title}</title>
% for style in include_styles:
  ${common.style(style)}
% endfor
% for script in include_scripts:
  ${common.script(script)}
% endfor
  </head>
  <body>
    ${next.main()}
  </body>
</html>

common.html

<%def name="script(src)">
  <script type="application/javascript" src="%{src | h}"></script>
</%def>

<%def name="style(href)">
  <link rel="stylesheet" type="text/css" href="${href | h}"/>
</%def>

的index.html

<%inherit file="page.html"/>
<%!

# Set document title.
title = "My Index"

# Set document scripts to include.
include_scripts = ['index.js']

# Set document styles to include.
include_styles = ['index.css']

%>

<%def name="main()">
  <h1>${title | h}</h1>
</%def>

这一切都呈现以下页面:

<!DOCTYPE html>


<html>
  <head>
    <title>My Index</title>
  </head>
  <body>

    <h1>My Index</h1>

  </body>
</html>

呈现的页面缺少样式,javascript包括我期望的应该是:

<!DOCTYPE html>


<html>
  <head>
    <title>My Index</title>
    <script type="application/javascript" src="index.js"></script>
    <link rel="stylesheet" type="text/css" href="index.css"/>
  </head>
  <body>

    <h1>My Index</h1>

  </body>
</html>

page.html 中,如果我打印context.namespaces,我会:

{('page_html', u'common'): <mako.runtime.TemplateNamespace object at 0x1e7d110>}

表示只有导入的 common.html 模板可用,但没有继承自 page.html 的后代模板名称空间。如何遍历继承模板名称空间并检查其属性?我知道我可以使用next来获取下一个模板命名空间,但是如果它存在,如何获得下一个模板命名空间?

1 个答案:

答案 0 :(得分:1)

page.html 中的代码段,用于检查include_scriptsinclude_styles属性的后代模板,必须遍历每个后代模板命名空间的next才能获取到下一个。仅使用context.namespaces列出本地命名空间。

import mako.runtime

# Scan for scripts and styles to include.
include_scripts = []
include_styles = []

# Start at the first descendant template.
ns = next
while isinstance(ns, mako.runtime.Namespace):
    if hasattr(ns.attr, 'include_scripts'):
        include_scripts.extend(ns.attr.include_scripts)
    if hasattr(ns.attr, 'include_styles'):
        include_styles.extend(ns.attr.include_styles)

    # NOTE: If the template namespace does not have *next* set, the built
    # in python function *next()* gets returned.
    ns = ns.context.get('next')