You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建独立容器的可折叠侧边导航栏并适配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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:57:35