使用 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 %}
我想在我的 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 %}