使用 Tornado 模板递归显示文件树结构

Recursively display file tree structure with Tornado template

我想在我的 html 页面上显示特定文件夹 (RESULTS) 内的文件树。我正在使用 python Tornado。我使用 the answer to this question 完成了大部分工作,并进行了修改以尝试使用 Tornado。

使用下面的代码,顶级目录显示为header,并显示顶级目录中的文件夹,但模板不会遍历子树中的项目。

这是渲染调用:

def get(self):
    logging.info("Loading Results tree...")
    self.render("results.html", tree=make_results_tree('RESULTS'))

这里是 make_results_tree 函数:

def make_results_tree(path):
    tree = dict(name=path, children=[])
    lst = os.listdir(path)
    if (path == 'RESULTS' and len(lst) == 1):
        tree['children'].append(dict(name="No results recorded for today"))
    else:
        for name in lst:
            fn = os.path.join(path, name)
            if os.path.isdir(fn):
                tree['children'].append(make_results_tree(fn))
            elif (name != '.gitkeep'):
                tree['children'].append(dict(name=name))
    return tree

我已经验证上面的 python 代码都按预期工作,因此问题出在下面的模板代码 (results.html) 中,可能在 if 或循环块中:

<div class="center">
  <h2>{{ tree['name'] }}</h2>
  <ul>
    {% for item in tree['children'] %}
      <li>{{ item['name'] }}
      {% if locals().get('item["children"]', False) %}
        <ul>{{ loop(item['children']) }}</ul>
      {% end %}</li>
    {% end %}
  </ul>
</div>

为什么模板代码没有遍历树的多个级别?

loop() 是 Jinja2 的一个特性; Tornado 模板中没有等效项。不要匿名递归,而是将文件拆分成两个文件,这样内部文件就可以递归调用自己。

此外,locals().get() 只执行简单的查找,它不能像 eval() 那样解析复杂的表达式。这里不需要locals,直接对item进行操作即可。

results.html:

<div class="center">
  <h2>{{ tree['name'] }}</h2>
  <ul>{% module Template('items.html', children=tree['children']) %}</ul>
</div>

items.html:

{% for item in children %}
  <li>{{ item['name'] }}
  {% if "children" in item %}
    <ul>{% module Template('items.html', children=item['children']) %}</ul>
  {% end %}</li>
{% end %}