必须拆分HTML多页项目,否则维护失控;需用{% extends %}继承base.html并仅在首行声明,配合{% block %}预留可替换区域,公共结构抽离为独立组件文件。

纯 HTML 多页项目必须拆成多个文件,否则维护会迅速失控
中大型项目如果只靠一个 index.html 堆功能,很快就会遇到路由跳转强制刷新、页面状态无法保留、SEO 不友好、改个页头要手动同步二十个文件等问题。这不是“推荐做法”,而是硬性约束——index.html 仅适合 SPA 场景(如 React/Vue 接管路由),纯静态多页应用(MPA)必须物理拆分。
关键判断标准就一条:你有没有在多个页面里复制粘贴相同的 <header>、<nav>、<footer>?如果有,说明你已经在用“伪继承”,只是没用模板机制而已。
- 拆分后每个页面对应真实 URL(如
/about.html、/contact.html),浏览器地址栏可直接访问、刷新不丢上下文 - 所有页面共用的结构(如导航栏)必须抽离为独立文件(如
components/header.html),再通过模板引擎引入 - 不要试图用原生
<iframe>或 JS 动态fetch拼接——这会让 SEO 和首屏加载变差,且无法被服务端正确解析
Django / Flask / FastAPI 中的 {% extends %} 必须写在第一行,且只能有一个
{% extends %} 是模板继承的入口指令,不是普通标签。它必须出现在子模板的**最开头**,前面不能有任何空格、注释或换行;否则渲染引擎会报错 TemplateSyntaxError: Invalid block tag on line X。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 子模板顶部有空行或 BOM 字符 → 报错
Could not parse the remainder - 写了两个
{% extends %}→ 直接崩溃,引擎不支持多重继承(Django/FastAPI/Jinja2 均如此) - 把
{% extends %}放在<html>标签内部 → 渲染结果错乱,部分区块内容丢失
正确写法示例(以 Django 为例):
{% extends 'base.html' %}
{% block title %}关于我们{% endblock %}
{% block content %}
<p>这里是关于页面正文</p>
{% endblock %}
base.html 里用 {% block %} 预留位置,但别把逻辑塞进 block 默认值里
{% block %} 的作用是声明“这里将来可能被替换”,不是写默认实现的容器。很多人习惯在 {% block main %}默认内容{% endblock %} 里塞完整 HTML 结构,结果子模板一覆盖就全丢——这违背了“父模板只管骨架”的设计原则。
真正该放进 base.html 的只有三类东西:
- 全局结构:DOCTYPE、
<html>、<head>开闭标签、固定<script src="/static/js/main.js"> - 预留占位:用空
{% block css %}{% endblock %}、{% block js %}{% endblock %}让子页按需注入资源 - 公共组件:用
{% include 'components/header.html' %}引入真正复用的片段(注意路径必须相对于 templates 目录)
错误示范:{% block content %}<div class="container"><h1>首页</h1></div>{% endblock %} —— 这会让所有子页都得重写整个容器结构。
静态站点生成器(如 Jekyll/Hugo)和手写模板的路径处理逻辑完全不同
如果你用的是 Python Web 框架(Django/FastAPI),模板路径基于 templates/ 目录,{% include 'header.html' %} 就去找 templates/header.html;但如果是 Jekyll,{% include header.html %} 默认从 _includes/ 目录读取,且不支持嵌套目录写法({% include components/header.html %} 会失败)。
更隐蔽的问题是相对路径引用:
- 在
base.html里写<link rel="stylesheet" href="css/base.css">,子页pages/about.html渲染时路径变成/pages/css/base.css(404) - 正确做法是统一用根路径:
href="/static/css/base.css",或由框架提供静态资源前缀(如 Django 的{% static 'css/base.css' %})
最容易被忽略的一点:不同模板引擎对路径大小写敏感程度不同。Jinja2 在 Linux 下严格区分 Header.html 和 header.html,而本地开发时 Windows 可能不报错,上线后直接 500。



















