You've already forked wp-bootstrap
feat: offcanvas mobile navigation with user avatar and admin bar fix (v1.0.11)
Switch mobile nav from collapse to offcanvas, add logged-in user avatar and My Account link to offcanvas header, move dark mode toggle to offcanvas footer. Fix admin bar overlapping offcanvas via inline CSS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,22 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.0.11] - 2026-02-28
|
||||
|
||||
### Changed
|
||||
|
||||
- **Offcanvas mobile navigation**: Default header now uses `header-offcanvas.html.twig` instead of `header.html.twig`. Mobile navigation slides in as an offcanvas panel from the right instead of collapsing downward.
|
||||
- **User avatar in offcanvas header**: When logged in, the offcanvas header displays the user's Gravatar and display name linking to the WooCommerce My Account page (or WP admin profile as fallback). Falls back to the site name when logged out.
|
||||
- **Dark mode toggle repositioned**: Moved from the offcanvas body to the offcanvas footer on mobile. Desktop toggle remains in the navbar.
|
||||
|
||||
### Added
|
||||
|
||||
- **User context data** (`inc/Template/ContextBuilder.php`): New `getUserData()` method exposing `user.logged_in`, `user.display_name`, `user.avatar`, and `user.account_url` to all Twig templates.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Admin bar overlapping offcanvas** (`functions.php`): Inline CSS via `wp_add_inline_style()` adds `padding-top` matching the admin bar height to `.offcanvas` when the admin bar is visible, preventing content overlap.
|
||||
|
||||
## [1.0.10] - 2026-02-25
|
||||
|
||||
### Fixed
|
||||
|
||||
30
CLAUDE.md
30
CLAUDE.md
@@ -34,7 +34,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
||||
|
||||
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file.
|
||||
|
||||
Current version is **v1.0.9**. See `PLAN.md` for details.
|
||||
Current version is **v1.0.11**. See `PLAN.md` for details.
|
||||
|
||||
## Technical Stack
|
||||
|
||||
@@ -234,6 +234,34 @@ Build steps (in order):
|
||||
|
||||
## Session History
|
||||
|
||||
### Session 17 — v1.0.11 Offcanvas Navigation & User Context (2026-02-28)
|
||||
|
||||
**Completed:** Switched mobile navigation from Bootstrap collapse to offcanvas, added logged-in user context to the header, and fixed admin bar overlap.
|
||||
|
||||
**What was changed:**
|
||||
|
||||
- **Offcanvas navigation** (`views/base.html.twig`): Default header include switched from `partials/header.html.twig` (collapse) to `partials/header-offcanvas.html.twig` (offcanvas slide-in from right). The offcanvas variant already existed in the theme.
|
||||
- **Offcanvas header with user avatar** (`views/partials/header-offcanvas.html.twig`): When logged in, the offcanvas header shows the user's Gravatar avatar and display name linking to the WooCommerce My Account page. Falls back to the site name when logged out.
|
||||
- **Dark mode toggle repositioned**: Moved from the offcanvas body to the offcanvas footer (`d-lg-none`) on mobile. On desktop (≥lg), the toggle remains visible next to the navbar via a separate `d-none d-lg-block` wrapper.
|
||||
- **User context in ContextBuilder** (`inc/Template/ContextBuilder.php`): New `getUserData()` method providing `user.logged_in`, `user.display_name`, `user.avatar` (rendered `<img>` with `rounded-circle` class), and `user.account_url` (WooCommerce My Account or WP admin profile fallback).
|
||||
- **Admin bar offcanvas overlap fix** (`functions.php`): Inline CSS injected via `wp_add_inline_style()` when `is_admin_bar_showing()` is true. Adds `padding-top: var(--wp-admin--admin-bar--height, 32px)` to `.offcanvas` so the offcanvas content clears the admin bar.
|
||||
|
||||
**Files modified:**
|
||||
|
||||
- `views/base.html.twig` — header include changed to offcanvas variant
|
||||
- `views/partials/header-offcanvas.html.twig` — user avatar header, dark mode toggle in footer
|
||||
- `inc/Template/ContextBuilder.php` — `getUserData()` method, `user` key in context
|
||||
- `functions.php` — admin bar offcanvas padding inline style
|
||||
- `style.css` — version bump to 1.0.11
|
||||
- `CHANGELOG.md` — v1.0.11 entry
|
||||
|
||||
**Key learnings:**
|
||||
|
||||
- Bootstrap offcanvas inside `navbar-expand-lg` uses `position: fixed; top: 0` which is covered by the WordPress admin bar (`z-index: 99999`). Since the offcanvas z-index (1045) is lower, adjusting `top` alone doesn't help visually — `padding-top` on the offcanvas content is the practical fix.
|
||||
- `wp_add_inline_style()` bypasses file-level browser caching, making it more reliable for conditional CSS rules than editing the main stylesheet.
|
||||
- WordPress's `--wp-admin--admin-bar--height` CSS custom property (set on `:root`) adjusts between 32px (desktop) and 46px (mobile ≤782px), making it the ideal value for admin bar offset calculations.
|
||||
- `get_avatar()` accepts an `$args` array where CSS classes can be passed via the `class` key, avoiding post-processing of the HTML output.
|
||||
|
||||
### Session 16 — v1.0.10 Title Double-Encoding Fix (2026-02-25)
|
||||
|
||||
**Completed:** Fixed double-encoding of HTML entities in page titles rendered through Twig.
|
||||
|
||||
@@ -83,6 +83,13 @@ if ( ! function_exists( 'wp_bootstrap_enqueue_scripts' ) ) :
|
||||
$theme_version
|
||||
);
|
||||
|
||||
// Push offcanvas below the WP admin bar when logged in.
|
||||
if ( is_admin_bar_showing() ) {
|
||||
wp_add_inline_style( 'wp-bootstrap-style',
|
||||
'.offcanvas { padding-top: var(--wp-admin--admin-bar--height, 32px); }'
|
||||
);
|
||||
}
|
||||
|
||||
// Enqueue Bootstrap JS bundle (includes Popper).
|
||||
wp_enqueue_script(
|
||||
'wp-bootstrap-js',
|
||||
|
||||
@@ -32,6 +32,7 @@ class ContextBuilder
|
||||
'layout' => 'default',
|
||||
'header_variant' => $this->getHeaderVariant(),
|
||||
'footer_variant' => $this->getFooterVariant(),
|
||||
'user' => $this->getUserData(),
|
||||
];
|
||||
|
||||
if (is_singular()) {
|
||||
@@ -93,6 +94,28 @@ class ContextBuilder
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user data for header/navigation.
|
||||
*/
|
||||
private function getUserData(): array
|
||||
{
|
||||
if (! is_user_logged_in()) {
|
||||
return ['logged_in' => false];
|
||||
}
|
||||
|
||||
$user = wp_get_current_user();
|
||||
$account_url = function_exists('wc_get_page_permalink')
|
||||
? wc_get_page_permalink('myaccount')
|
||||
: admin_url('profile.php');
|
||||
|
||||
return [
|
||||
'logged_in' => true,
|
||||
'display_name' => $user->display_name,
|
||||
'avatar' => get_avatar($user->ID, 32, '', '', ['class' => 'rounded-circle']),
|
||||
'account_url' => $account_url,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get navigation menu items for a location.
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: A modern WordPress Block Theme built from scratch with Bootstrap 5.
|
||||
Requires at least: 6.7
|
||||
Tested up to: 6.7
|
||||
Requires PHP: 8.3
|
||||
Version: 1.0.10
|
||||
Version: 1.0.11
|
||||
License: GNU General Public License v2 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
Text Domain: wp-bootstrap
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<a class="wp-bootstrap-skip-link" href="#main-content">{{ __('Skip to main content') }}</a>
|
||||
|
||||
{% block header %}
|
||||
{% include 'partials/header.html.twig' %}
|
||||
{% include 'partials/header-offcanvas.html.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
<main id="main-content" class="{% block main_class %}py-4{% endblock %}">
|
||||
|
||||
@@ -15,7 +15,14 @@
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="navbarOffcanvas"
|
||||
aria-labelledby="navbarOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="navbarOffcanvasLabel">{{ site.name }}</h5>
|
||||
{% if user.logged_in %}
|
||||
<a href="{{ user.account_url }}" class="d-flex align-items-center text-decoration-none">
|
||||
{{ user.avatar|raw }}
|
||||
<span class="ms-2 fw-semibold">{{ user.display_name|esc_html }}</span>
|
||||
</a>
|
||||
{% else %}
|
||||
<h5 class="offcanvas-title" id="navbarOffcanvasLabel">{{ site.name }}</h5>
|
||||
{% endif %}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"
|
||||
aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
@@ -54,12 +61,19 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if dark_mode %}
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if dark_mode %}
|
||||
<div class="offcanvas-footer d-lg-none border-top p-3">
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{%- if dark_mode %}
|
||||
<div class="d-none d-lg-block ms-2">
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
Reference in New Issue
Block a user