You've already forked wp-bootstrap
Replace FSE block markup on the frontend with proper Bootstrap 5 HTML rendered through Twig templates. The Site Editor remains functional for admin editing while the public site outputs Bootstrap navbar, cards, pagination, grid layout, and responsive components. New PHP classes: TemplateController, ContextBuilder, NavWalker New Twig templates: 20 files (base, pages, partials, components) Enhanced TwigService with WordPress functions and globals Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
2.1 KiB
PHP
81 lines
2.1 KiB
PHP
<?php
|
|
/**
|
|
* Bootstrap 5 Navigation Walker.
|
|
*
|
|
* Converts flat WordPress menu items into a nested tree
|
|
* suitable for rendering Bootstrap navbar dropdowns in Twig.
|
|
*
|
|
* @package WPBootstrap
|
|
* @since 0.1.1
|
|
*/
|
|
|
|
namespace WPBootstrap\Template;
|
|
|
|
class NavWalker
|
|
{
|
|
/**
|
|
* Build a nested menu tree from flat WordPress menu items.
|
|
*
|
|
* @param array $items Array of WP_Post menu item objects.
|
|
* @return array Nested array suitable for Twig iteration.
|
|
*/
|
|
public function buildTree(array $items): array
|
|
{
|
|
$tree = [];
|
|
$children = [];
|
|
|
|
foreach ($items as $item) {
|
|
$node = [
|
|
'id' => (int) $item->ID,
|
|
'title' => $item->title,
|
|
'url' => $item->url,
|
|
'target' => $item->target ?: '',
|
|
'classes' => implode(' ', array_filter($item->classes ?? [])),
|
|
'active' => $this->isActive($item),
|
|
'children' => [],
|
|
];
|
|
|
|
if ((int) $item->menu_item_parent === 0) {
|
|
$tree[$item->ID] = $node;
|
|
} else {
|
|
$children[(int) $item->menu_item_parent][] = $node;
|
|
}
|
|
}
|
|
|
|
// Assign children to their parent items.
|
|
foreach ($children as $parentId => $childItems) {
|
|
if (isset($tree[$parentId])) {
|
|
$tree[$parentId]['children'] = $childItems;
|
|
}
|
|
}
|
|
|
|
return array_values($tree);
|
|
}
|
|
|
|
/**
|
|
* Determine if a menu item is currently active.
|
|
*/
|
|
private function isActive(object $item): bool
|
|
{
|
|
$classes = $item->classes ?? [];
|
|
|
|
if (in_array('current-menu-item', $classes, true)) {
|
|
return true;
|
|
}
|
|
|
|
if (in_array('current-menu-ancestor', $classes, true)) {
|
|
return true;
|
|
}
|
|
|
|
if ($item->object === 'page' && is_page((int) $item->object_id)) {
|
|
return true;
|
|
}
|
|
|
|
if ($item->object === 'category' && is_category((int) $item->object_id)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|