- Implemented comprehensive trainer navigation system:
* Horizontal and vertical navigation layouts
* Multi-level menu with dropdowns for Events, Venues, Organizers, Profile
* Responsive mobile navigation with hamburger menu
* Keyboard navigation support (Arrow keys, Enter, Escape)
* Active page highlighting
* Master trainer menu items for users with appropriate role
- Created breadcrumb system:
* Automatic breadcrumb generation based on URL structure
* Shortcode support [hvac_breadcrumbs]
* SEO-friendly with structured data (Schema.org)
* Multiple style options (default, pills, arrows)
* Responsive design
- Technical implementation:
* HVAC_Trainer_Navigation class for menu management
* HVAC_Breadcrumbs class for breadcrumb generation
* CSS for both navigation and breadcrumbs
* JavaScript for interactive menu behaviors
* Template part for easy inclusion
Navigation provides easy access to all trainer features and improves UX.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
267 lines
No EOL
9.5 KiB
PHP
267 lines
No EOL
9.5 KiB
PHP
<?php
|
||
/**
|
||
* HVAC Breadcrumbs System
|
||
*
|
||
* @package HVAC_Community_Events
|
||
* @since 2.0.0
|
||
*/
|
||
|
||
if (!defined('ABSPATH')) {
|
||
exit;
|
||
}
|
||
|
||
/**
|
||
* HVAC_Breadcrumbs class
|
||
*/
|
||
class HVAC_Breadcrumbs {
|
||
|
||
/**
|
||
* Constructor
|
||
*/
|
||
public function __construct() {
|
||
// Register shortcode
|
||
add_shortcode('hvac_breadcrumbs', array($this, 'render_breadcrumbs'));
|
||
|
||
// Auto-add breadcrumbs to trainer pages
|
||
add_action('hvac_after_page_header', array($this, 'display_breadcrumbs'));
|
||
|
||
// Enqueue styles
|
||
add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
|
||
}
|
||
|
||
/**
|
||
* Enqueue breadcrumb styles
|
||
*/
|
||
public function enqueue_styles() {
|
||
if ($this->should_show_breadcrumbs()) {
|
||
wp_enqueue_style(
|
||
'hvac-breadcrumbs',
|
||
HVAC_PLUGIN_URL . 'assets/css/hvac-breadcrumbs.css',
|
||
array(),
|
||
HVAC_PLUGIN_VERSION
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get breadcrumb trail
|
||
*/
|
||
private function get_breadcrumb_trail() {
|
||
$trail = array();
|
||
$current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
|
||
|
||
// Always start with home
|
||
$trail[] = array(
|
||
'label' => 'Home',
|
||
'url' => home_url('/')
|
||
);
|
||
|
||
// Check if we're on a trainer page
|
||
if (strpos($current_url, '/trainer/') !== false) {
|
||
$trail[] = array(
|
||
'label' => 'Trainer',
|
||
'url' => '/trainer/dashboard/'
|
||
);
|
||
|
||
// Parse the current path
|
||
$path = parse_url($current_url, PHP_URL_PATH);
|
||
$path = trim($path, '/');
|
||
$segments = explode('/', $path);
|
||
|
||
// Remove 'trainer' from segments as we've already added it
|
||
array_shift($segments);
|
||
|
||
// Build breadcrumb based on URL segments
|
||
if (!empty($segments)) {
|
||
$breadcrumb_map = $this->get_breadcrumb_map();
|
||
$current_path = '/trainer';
|
||
|
||
foreach ($segments as $index => $segment) {
|
||
$current_path .= '/' . $segment;
|
||
|
||
// Check if we have a mapping for this path
|
||
if (isset($breadcrumb_map[$current_path])) {
|
||
$is_last = ($index === count($segments) - 1);
|
||
|
||
$trail[] = array(
|
||
'label' => $breadcrumb_map[$current_path]['label'],
|
||
'url' => $is_last ? null : $current_path . '/',
|
||
'current' => $is_last
|
||
);
|
||
}
|
||
}
|
||
}
|
||
} elseif (strpos($current_url, '/master-trainer/') !== false) {
|
||
$trail[] = array(
|
||
'label' => 'Master Trainer',
|
||
'url' => '/master-trainer/master-dashboard/'
|
||
);
|
||
|
||
// Similar logic for master trainer pages
|
||
$path = parse_url($current_url, PHP_URL_PATH);
|
||
$path = trim($path, '/');
|
||
$segments = explode('/', $path);
|
||
array_shift($segments); // Remove 'master-trainer'
|
||
|
||
if (!empty($segments)) {
|
||
$breadcrumb_map = $this->get_breadcrumb_map();
|
||
$current_path = '/master-trainer';
|
||
|
||
foreach ($segments as $index => $segment) {
|
||
$current_path .= '/' . $segment;
|
||
|
||
if (isset($breadcrumb_map[$current_path])) {
|
||
$is_last = ($index === count($segments) - 1);
|
||
|
||
$trail[] = array(
|
||
'label' => $breadcrumb_map[$current_path]['label'],
|
||
'url' => $is_last ? null : $current_path . '/',
|
||
'current' => $is_last
|
||
);
|
||
}
|
||
}
|
||
}
|
||
} elseif (strpos($current_url, '/trainer-registration/') !== false) {
|
||
$trail[] = array(
|
||
'label' => 'Registration',
|
||
'url' => null,
|
||
'current' => true
|
||
);
|
||
}
|
||
|
||
// Allow filtering of breadcrumb trail
|
||
return apply_filters('hvac_breadcrumb_trail', $trail, $current_url);
|
||
}
|
||
|
||
/**
|
||
* Get breadcrumb mapping
|
||
*/
|
||
private function get_breadcrumb_map() {
|
||
return array(
|
||
// Trainer pages
|
||
'/trainer/dashboard' => array('label' => 'Dashboard'),
|
||
'/trainer/event' => array('label' => 'Events'),
|
||
'/trainer/event/manage' => array('label' => 'Manage Event'),
|
||
'/trainer/event-summary' => array('label' => 'Event Summary'),
|
||
'/trainer/generate-certificates' => array('label' => 'Generate Certificates'),
|
||
'/trainer/certificate-reports' => array('label' => 'Certificate Reports'),
|
||
'/trainer/venue' => array('label' => 'Venues'),
|
||
'/trainer/venue/list' => array('label' => 'List'),
|
||
'/trainer/venue/manage' => array('label' => 'Manage'),
|
||
'/trainer/organizer' => array('label' => 'Organizers'),
|
||
'/trainer/organizer/list' => array('label' => 'List'),
|
||
'/trainer/organizer/manage' => array('label' => 'Manage'),
|
||
'/trainer/profile' => array('label' => 'Profile'),
|
||
'/trainer/profile/edit' => array('label' => 'Edit'),
|
||
|
||
// Master trainer pages
|
||
'/master-trainer/master-dashboard' => array('label' => 'Master Dashboard'),
|
||
'/master-trainer/trainers' => array('label' => 'All Trainers'),
|
||
'/master-trainer/reports' => array('label' => 'Global Reports')
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Render breadcrumbs shortcode
|
||
*/
|
||
public function render_breadcrumbs($atts = array()) {
|
||
$atts = shortcode_atts(array(
|
||
'separator' => '›',
|
||
'show_home' => 'yes',
|
||
'home_label' => 'Home',
|
||
'class' => 'hvac-breadcrumb'
|
||
), $atts);
|
||
|
||
$trail = $this->get_breadcrumb_trail();
|
||
|
||
if (empty($trail)) {
|
||
return '';
|
||
}
|
||
|
||
// Remove home if requested
|
||
if ($atts['show_home'] === 'no' && !empty($trail)) {
|
||
array_shift($trail);
|
||
} else if (!empty($trail) && $atts['home_label'] !== 'Home') {
|
||
$trail[0]['label'] = $atts['home_label'];
|
||
}
|
||
|
||
ob_start();
|
||
?>
|
||
<nav class="<?php echo esc_attr($atts['class']); ?>" aria-label="Breadcrumb">
|
||
<ol class="hvac-breadcrumb-list">
|
||
<?php foreach ($trail as $index => $item): ?>
|
||
<li class="hvac-breadcrumb-item<?php echo isset($item['current']) && $item['current'] ? ' hvac-breadcrumb-current' : ''; ?>">
|
||
<?php if (!empty($item['url']) && (!isset($item['current']) || !$item['current'])): ?>
|
||
<a href="<?php echo esc_url($item['url']); ?>" class="hvac-breadcrumb-link">
|
||
<?php echo esc_html($item['label']); ?>
|
||
</a>
|
||
<?php else: ?>
|
||
<span class="hvac-breadcrumb-text" aria-current="page">
|
||
<?php echo esc_html($item['label']); ?>
|
||
</span>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($index < count($trail) - 1): ?>
|
||
<span class="hvac-breadcrumb-separator" aria-hidden="true">
|
||
<?php echo esc_html($atts['separator']); ?>
|
||
</span>
|
||
<?php endif; ?>
|
||
</li>
|
||
<?php endforeach; ?>
|
||
</ol>
|
||
</nav>
|
||
<?php
|
||
return ob_get_clean();
|
||
}
|
||
|
||
/**
|
||
* Display breadcrumbs automatically
|
||
*/
|
||
public function display_breadcrumbs() {
|
||
if ($this->should_show_breadcrumbs()) {
|
||
echo do_shortcode('[hvac_breadcrumbs]');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if breadcrumbs should be shown
|
||
*/
|
||
private function should_show_breadcrumbs() {
|
||
// Show on all trainer and master trainer pages
|
||
$current_url = home_url(add_query_arg(array(), $GLOBALS['wp']->request));
|
||
|
||
return strpos($current_url, '/trainer/') !== false ||
|
||
strpos($current_url, '/master-trainer/') !== false ||
|
||
strpos($current_url, '/trainer-registration/') !== false;
|
||
}
|
||
|
||
/**
|
||
* Get structured data for breadcrumbs (SEO)
|
||
*/
|
||
public function get_structured_data() {
|
||
$trail = $this->get_breadcrumb_trail();
|
||
|
||
if (empty($trail)) {
|
||
return '';
|
||
}
|
||
|
||
$items = array();
|
||
|
||
foreach ($trail as $index => $item) {
|
||
$items[] = array(
|
||
'@type' => 'ListItem',
|
||
'position' => $index + 1,
|
||
'name' => $item['label'],
|
||
'item' => !empty($item['url']) ? home_url($item['url']) : null
|
||
);
|
||
}
|
||
|
||
$structured_data = array(
|
||
'@context' => 'https://schema.org',
|
||
'@type' => 'BreadcrumbList',
|
||
'itemListElement' => $items
|
||
);
|
||
|
||
return '<script type="application/ld+json">' . json_encode($structured_data, JSON_UNESCAPED_SLASHES) . '</script>';
|
||
}
|
||
}
|