jinja2模板错位问题

摘要

本文探讨了在使用Jinja2模板时,由于嵌套<a>标签导致的HTML结构错位问题。作者通过示例展示了模板代码及其渲染结果,指出问题的核心在于HTML规范中不允许<a>标签嵌套,导致渲染结果与预期不符。为解决此问题,作者提出了优化方案:移除嵌套的<a>标签,并通过onclick事件实现跳转功能,从而避免了结构错位。文章详细分析了问题的原因,并提供了改进后的代码示例,展示了如何正确渲染嵌套结构。本文对前端开发中使用Jinja2模板的开发者具有参考价值,尤其是处理复杂HTML结构时的潜在问题。



问题

我有以下模板:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<div class="grid">
    {% for item in data.data %}
    <a href={{ item.link }} class="card">
        <span class="cardindex">{{ loop.index }}. &nbsp;&nbsp;</span>
        <span class="cardtitle">{{ item.title }}</span>
        <div class="carddetail">
            <span class="cardate">{{ item.date }}</span>
            <a href={{ item.home }} class="cardhome">
                <span class="cardauthor">{{ item.author }}</span>
            </a>
        </div>
    </a>
    {% endfor %}
</div>

渲染之后看到浏览器显示是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<a href="******" class="card">
    <span class="cardindex">1. &nbsp;&nbsp;</span>
    <span class="cardtitle">******</span>
</a>
<div class="carddetail">
    <a href="******" class="card">
        <span class="cardate">******</span>
    </a>
    <a href="******" class="cardhome">
        <span class="cardauthor">******</span>
    </a>
</div>

明显不符合要求, 按照模板的结构carddetail应该是card的child.

解决

通过渲染结果可以大概分析出是a标签嵌套导致的错位(TODO: 为什么嵌套a标签会导致错位?), 注释第二个a标签可以正确渲染.

那么, 解决方案如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<div class="grid">
    {% for item in data.data %}
    <a href="{{ item.link }}" target="blank" class="card">
        <span class="cardindex">{{ loop.index }}. </span>
        <span class="cardtitle">{{ item.title }}</span>
        <div class="carddetail">
            <span class="cardate">{{ item.date }}</span>
            <span class="cardauthor cardhome" onclick="javascript:window.open('{{ item.home }}')">{{ item.author }}</span>
        </div>
    </a>
    {% endfor %}
</div>

移除了a标签, 并且使用onclick事件来实现跳转.