如何构建独立容器的可折叠侧边导航栏并适配Jinja2模板继承
解决Jinja2模板继承下的可折叠侧边导航栏布局问题
问题背景
我正在开发一款应用,需要实现可折叠侧边导航栏,且希望通过Jinja2模板继承复用该导航栏,无需在每个页面重复构建。但目前无法实现侧边导航栏与主内容分属独立外层div的布局,导致无法正常使用模板继承。
解决方案
核心思路是把固定不变的布局(侧边栏、顶部导航)封装到基础模板中,为主内容区域预留可替换的模板块,子页面通过继承基础模板并填充对应块的内容来实现复用。
步骤1:重构基础模板(base.html)
将原代码拆分为固定部分和可变部分,用Jinja2的{% block %}标记主内容的可变区域:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 引入依赖样式 --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <title>{% block title %}BusinessAssistant{% endblock %}</title> <!-- 侧边栏自定义样式 --> <style> #sidebar { min-width: 250px; max-width: 250px; transition: all 0.3s; } #sidebar.collapsed { min-width: 80px; max-width: 80px; text-align: center; } .wrapper { display: flex; width: 100%; } .main { width: 100%; } </style> </head> <body> <div id="main-wrap" class="wrapper"> <!-- 固定侧边栏 --> <aside id="sidebar"> <div class="h-100"> <div class="sidebar-logo"> <a href="{{ url_for('home') }}">BusinessAssistant</a> </div> <ul class="sidebar-nav"> <li class="sidebar-header">Admin Elements</li> <li class="sidebar-item"> <a href="{{ url_for('dashboard') }}" class="sidebar-link"> <i class="fa-solid fa-list pe-2"></i>Dashboard </a> </li> <li class="sidebar-item"> <a href="#" class="sidebar-link collapsed" data-bs-target="#documents" data-bs-toggle="collapse" aria-expanded="false"> <i class="fa-solid fa-file-lines pe-2"></i>Documents </a> <ul id="documents" class="sidebar-dropdown list-unstyled collapse" data-bs-parent="#sidebar"> <li class="sidebar-item"> <a href="{{ url_for('upload_docs') }}" class="sidebar-link">Upload Documents</a> </li> <li class="sidebar-item"> <a href="{{ url_for('view_docs') }}" class="sidebar-link">View Documents</a> </li> </ul> </li> <li class="sidebar-item"> <a href="#" class="sidebar-link"> <i class="fa-solid fa-circle-info pe-2"></i>Help </a> </li> </ul> </div> </aside> <!-- 主内容区域 --> <div class="main"> <!-- 固定顶部导航 --> <nav class="navbar navbar-expand px-3 border-bottom"> <button class="btn" id="sidebar-toggle" type="button"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse navbar"> <ul class="navbar-nav"> <li class="nav-item dropdown"> <a href="#" data-bs-toggle="dropdown" class="nav-icon pe-md-0"> <i class="fa-regular fa-circle-user fa-2xl" style="color: #e9ecef;"></i> </a> <div class="dropdown-menu dropdown-menu-end"> <a href="#" class="dropdown-item">Account</a> <a href="{{ url_for('logout') }}" class="dropdown-item">Logout</a> </div> </li> </ul> </div> </nav> <!-- 可变内容块:子页面将填充这里 --> <main class="content py-2"> {% block content %}{% endblock %} </main> </div> </div> <!-- 依赖脚本 --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script> // 侧边栏折叠逻辑,全局复用 const sidebarToggle = document.getElementById('sidebar-toggle'); const sidebar = document.getElementById('sidebar'); sidebarToggle.addEventListener('click', () => { sidebar.classList.toggle('collapsed'); }); </script> </body> </html>
步骤2:创建子页面(示例:dashboard.html)
子页面通过{% extends "base.html" %}继承基础模板,仅填充自身业务内容:
{% extends "base.html" %} {% block title %}Dashboard - BusinessAssistant{% endblock %} {% block content %} <div class="response-bar"> <div class="ressi"> <div class="res"> <h1>欢迎来到仪表盘</h1> <p>这里是仪表盘的专属内容区域</p> </div> </div> </div> <div class="sub-bar"> <!-- 子页面自定义内容 --> </div> {% endblock %}
关键说明
- 固定布局(侧边栏、顶部导航、折叠交互)全部放在基础模板,子页面无需重复编写。
- 子页面仅需关注自身业务内容,通过
content块实现差异化。 - 原布局结构完全保留,不会影响侧边栏的折叠功能。
内容的提问来源于stack exchange,提问作者theNewGuy
相关产品推荐
相关产品推荐

