Layout
The page shell — header, sidebar, main content area and footer — how it's composed from PUG mixins, and the sticky-header and responsive behavior.
Every page is built from the same shell: a top header/navbar, a left sidebar, the main content area (with a sticky page header), and a footer. In the canonical HTML edition the shell is assembled in PUG from reusable mixins, then compiled to static HTML. This page documents both — the mixins you call and the markup they produce.
How the shell is composed (PUG)
A page template includes the common partials and calls four mixins. The header, sidebar, page
header and footer each come from a mixin; your content goes inside main, in .pageWrapper:
include common_pages/mainInclude
include common_pages/pageHeader
include common_pages/mixins/panelCard
include common_pages/mixins/colLayout
+headSection({ title: 'My Page | Taxi CRM', canonical: 'myPage.html' })
+loadingScreen()
+headerSection({ showPrimaryNav: false }) // top navbar
+sidebarSection() // left rail
main.d-flex.flex-column.has-sticky-header
+pageHeader({ currentPage: 'myPage.html', fixed: true }) // title + breadcrumb
.d-flex.flex-column.pageWrapper
// ▼ YOUR PAGE CONTENT ▼
include common_pages/notifications
include common_pages/chatApp
+footerSection() // footerMixin config flags drive the layout variants (showPrimaryNav, fixedNav, fixed,
fixedFooter, bodyClass) — see Page Layouts.
Page shell — compiled markup
The mixins above compile to this structure:
<!-- 1. Header / top navbar (wrapped in #app-main) -->
<div class="d-flex flex-column app-main" id="app-main">
<header class="d-flex app-page flex-column"> … </header>
</div>
<!-- 2. Sidebar -->
<aside class="app-sidebar flex-column drawer drawer-start"> … </aside>
<!-- 3. Main content -->
<main class="d-flex flex-column has-sticky-header">
<div class="page-header page-header-default page-header-fixed"> … </div>
<div class="d-flex flex-column pageWrapper">
<!-- ▼ YOUR PAGE CONTENT ▼ -->
</div>
</main>
<!-- 4. Footer -->
<footer class="app-footer"> … </footer>Key hooks:
| Element | Class / id | Purpose |
|---|---|---|
| App wrapper | #app-main / .app-main | Flex container the headerSection mixin wraps the header in. |
| Main area | main.has-sticky-header | Reserves space for the pinned navbar and enables the sticky page-header behavior. |
| Page header | .page-header.page-header-default.page-header-fixed | Title + breadcrumb bar (page-header-fixed makes it sticky). |
| Content slot | .pageWrapper | Put your page content here. |
Header / top navbar
<header class="d-flex app-page flex-column">
<!-- Slide-down search -->
<form class="site-search" method="get">
<input type="text" name="site_search" placeholder="Type to search..." autocomplete="off">
<div class="search-tools">
<span class="clear-search">Clear</span>
<span class="close-search"><span class="material-symbols-sharp">close</span></span>
</div>
</form>
<nav class="navbar navbar-expand-md fixed-top">
<div class="container-fluid ps-0 pe-0">
<!-- Brand (mobile) -->
<div class="d-flex align-items-center" id="mobileBrandingLink">
<a class="d-flex align-items-center text-decoration-none" href="dashboard.html">
<img alt="Taxi CRM Logo" height="38" src="assets/img/logo/logo.png" width="38">
<span class="text-nowrap fs-4 ms-2">Taxi CRM</span>
</a>
</div>
<!-- Sidebar toggle (mobile) -->
<div class="me-1 me-md-2" id="sidebarTrigger">
<span class="material-symbols-sharp btn btn-primary btn-sm">menu</span>
</div>
<!-- Minify sidebar (desktop) -->
<div class="d-lg-flex me-1 me-md-2" id="minifySidebar">
<span class="material-symbols-sharp btn btn-primary btn-sm">menu</span>
</div>
<!-- Primary nav (optional quick-access dropdowns) -->
<div class="collapse navbar-collapse" id="primaryNav">
<ul class="navbar-nav align-items-center"> … </ul>
</div>
<!-- Right-side actions -->
<div class="collapse navbar-collapse" id="navbarActions">
<ul class="navbar-nav">
<li class="nav-item languageSwitcher w-auto"> … </li> <!-- language switcher -->
<li class="nav-item">
<button class="header-nav-link btn border-0 btn-lg btn-icons theme-toggle" id="themeToggle" type="button">
<span class="material-symbols-sharp">dark_mode</span>
</button>
</li>
<li class="nav-item searchBar"> … </li> <!-- opens .site-search -->
<li class="nav-item appItems"> … </li> <!-- apps dropdown -->
<li class="nav-item dropdown notification" data-bs-toggle="offcanvas" data-bs-target="#notificationsOffcanvas">
<span class="notification-count">8</span> …
</li>
<li class="nav-item" data-bs-toggle="offcanvas" data-bs-target="#chat-app"> … </li> <!-- messages -->
<li class="nav-item">
<button class="header-nav-link btn border-0 btn-lg btn-icons" id="toggleFullScreen" type="button">
<span class="material-symbols-sharp">fullscreen</span>
</button>
</li>
<li class="nav-item userProfile"> … </li> <!-- user/profile dropdown -->
</ul>
</div>
</div>
</nav>
</header>The header behaviors (theme toggle via #themeToggle, language switcher, fullscreen, search,
sidebar minify) are wired up automatically by assets/js/core/app.js — see
JavaScript. The notifications and chat panels live in shared
offcanvas markup pulled in by include common_pages/notifications and include common_pages/chatApp
(#notificationsOffcanvas, #chat-app).
Sidebar
<aside class="app-sidebar flex-column drawer drawer-start">
<div class="d-flex" id="brandingLink">
<a class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-decoration-none" href="dashboard.html">
<img alt="Taxi CRM Logo" height="44" src="assets/img/logo/logo.png" width="44">
<span class="text-nowrap">Taxi CRM</span>
</a>
</div>
<div class="d-flex flex-column flex-shrink-0" id="navigations">
<ul class="nav nav-pills flex-row mb-auto addSlimScroll">
<div class="nav-hover-bg"></div>
<div class="nav-active-bg"></div>
<!-- Section divider -->
<li class="nav-item divider">
<span class="text">Taxi Booking</span>
<span class="material-symbols-sharp">filter_list</span>
</li>
<!-- Collapsible group with children -->
<li class="nav-item nav-accordion active">
<span class="nav-link">
<span class="make_icon material-symbols-sharp">database</span>
<span class="nav-title">Masters</span>
<span class="nav-arrow"></span>
</span>
<div class="nav-sub nav-sub-accordion">
<div class="nav-item-sub active">
<a class="nav-link" href="roleMaster.html"><span class="nav-title">Role Master</span></a>
<a class="nav-add-icon" href="addRoleMaster.html" title="Add Role">
<span class="material-symbols-sharp">add</span>
</a>
</div>
<!-- more .nav-item-sub … -->
</div>
</li>
<!-- Plain item with no children -->
<li class="nav-item no-child">
<a class="nav-link" href="faqPage.html">
<span class="make_icon material-symbols-sharp">help</span>
<span class="nav-title">FAQ Page</span>
</a>
</li>
</ul>
</div>
</aside>Sidebar class reference:
| Class | Role |
|---|---|
nav-accordion | Collapsible menu group (shows the nav-arrow chevron). Add active to expand/highlight. |
nav-sub / nav-sub-accordion | The submenu container, revealed when the group is open. |
nav-item-sub | A single submenu entry (link + optional nav-add-icon). |
no-child | A top-level item that links directly (no submenu). |
make_icon + material-symbols-sharp | The leading menu icon. |
nav-title | The menu label (translate with data-i18n). |
divider | A section heading inside the menu. |
addSlimScroll | Applies the slim-scroll plugin to the menu list. |
In the HTML edition the whole menu is data-driven: aside.pug iterates the ITEMS menu
structure (asideItems.pug) to emit these .nav-accordion / .nav-item-sub / .no-child
items, sets active automatically by matching the current page, and pulls "Add" shortcuts from
ADD_PAGE_MAP. The markup above is what one entry compiles to.
To highlight the current page (in plain compiled HTML): add active to its .nav-item-sub
(and to the parent .nav-accordion), or to its .nav-item.no-child.
Footer
<footer class="app-footer">
<nav class="navbar navbar-expand-lg fixed-bottom">
<div class="container-fluid navbar-brand">
<div class="d-flex flex-column">
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link active" aria-current="page" href="dashboard.html">Home</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0)">Website</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0)">Portfolio</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0)">Terms</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0)">License</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0)">Privacy Policy</a></li>
</ul>
</div>
<div class="text-dark pb-0">
<span class="me-2">© 2026</span>
<a class="text-dark me-0" href="http://www.pvrtechstudio.com/">PVR Tech Studio</a>
</div>
</div>
</nav>
</footer>The footer mixin takes fixedFooter (default true) — set +footerSection({ fixedFooter: false })
to drop fixed-bottom.
Page header (title + breadcrumb)
The page header is generated by the pageHeader / autoPageHeader mixin. You pass the current
page and it auto-resolves the title and breadcrumb by looking the page up in the ITEMS
menu structure; it can also render a right-aligned stats strip (Bookings / Drivers / Revenue
with sparklines) when showStats is on:
+pageHeader({ currentPage: 'roleMaster.html', fixed: true })That compiles to:
<div class="page-header page-header-default page-header-fixed">
<div class="page-header-content d-flex justify-content-between align-items-end">
<div class="page-title">
<h5><span class="fw-bold">Role Master</span><span> - </span><span>Masters</span></h5>
<ul class="breadcrumb d-flex flex-wrap list-unstyled mb-0">
<li><a class="text-primary text-decoration-none" href="dashboard.html">Home</a></li>
<li><a class="text-primary text-decoration-none" href="javascript:void(0)">Masters</a></li>
<li class="active text-secondary"><span>Role Master</span></li>
</ul>
</div>
<!-- optional: #breadcrumb-right stats with .sparkline -->
</div>
</div>fixed: true adds page-header-fixed (sticky); fixed: false lets the bar scroll away.
Responsive & mobile behavior
The sidebar is a drawer drawer-start rail. On wide screens it sits beside the content; below
the navbar's navbar-expand-md breakpoint the hamburger (#sidebarTrigger, in the header)
slides it in as an off-canvas drawer. On desktop, #minifySidebar toggles the icon-only
minified state, which simply reduces --app-width-lhs from 16.5625rem to 5.625rem. Loading
a page with <body class="minSidebar"> starts in that collapsed state.
Breakpoints come from 01-variable.less (500 / 767 / 799 / 991 / 992 / 1149 / 1150px and more)
— see CSS System.
Layout variants
The kit ships demo pages showing different header / footer / sidebar modes, each produced by
flipping a mixin config flag (showPrimaryNav, fixedNav, fixed, fixedFooter, bodyClass).
For the full list of variants, the exact flags, and which classes they emit, see
Page Layouts.
Was this page helpful?
