Skip to main content
 首页 » 编程设计

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

2025年05月04日9kevingrace

我正在尝试理解 Version One - Use Namespace.attr在 Mako 中访问后代属性的示例。我在 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 获取下一个模板命名空间,但如果存在下一个模板命名空间,我该如何获取它呢?

请您参考如下方法:

page.html 中的代码片段用于检查 include_scripts 的后代模板和 include_styles属性必须遍历 next每个后代模板 namespace 的下一个。使用 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')