JezK
Edit File: advaxe-header.php
<?php /* Plugin Name: Advaxe Custom Header Description: Custom WooCommerce Header with Separate Desktop/Mobile Topbars, HTML/CSS Support, and Premium Admin UI. Version: 4.4 Author: Advaxe */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * 1. Load Scripts (Color Picker and Media Uploader) */ function advaxe_admin_scripts( $hook ) { if ( 'toplevel_page_advaxe-header' !== $hook ) { return; } wp_enqueue_media(); wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_script( 'wp-color-picker' ); } add_action( 'admin_enqueue_scripts', 'advaxe_admin_scripts' ); /** * 2. Admin Menu */ function advaxe_add_admin_menu() { add_menu_page( 'Advaxe Header', 'Advaxe Header', 'manage_options', 'advaxe-header', 'advaxe_settings_page_html', 'dashicons-layout', 99 ); } add_action( 'admin_menu', 'advaxe_add_admin_menu' ); /** * 3. Register Settings */ function advaxe_settings_init() { register_setting( 'advaxe_plugin_options', 'advaxe_settings' ); } add_action( 'admin_init', 'advaxe_settings_init' ); /** * 4. Premium Admin Page HTML */ function advaxe_settings_page_html() { $options = get_option( 'advaxe_settings', array() ); ?> <div class="wrap advaxe-admin-wrap"> <h1 class="wp-heading-inline">Advaxe Header Settings</h1> <hr class="wp-header-end"> <form action="options.php" method="post" style="margin-top: 20px;"> <?php settings_fields( 'advaxe_plugin_options' ); ?> <div class="advaxe-admin-grid"> <div class="advaxe-card"> <h3><span class="dashicons dashicons-admin-generic"></span> General Settings</h3> <div class="card-content"> <label>Logo Upload</label> <div class="upload-flex"> <input type="text" name="advaxe_settings[logo_url]" id="advaxe_logo_url" value="<?php echo esc_attr($options['logo_url'] ?? ''); ?>" class="regular-text"> <input type="button" id="advaxe_upload_btn" class="button button-secondary" value="Select Image"> </div> <div id="advaxe_logo_preview" class="logo-preview-box"> <?php if(!empty($options['logo_url'])): ?> <img src="<?php echo esc_url($options['logo_url']); ?>" style="max-height: 50px;"> <?php else: ?> <p>No logo selected</p> <?php endif; ?> </div> <br> <label>Header Phone Number</label> <input type="text" name="advaxe_settings[phone_number]" value="<?php echo esc_attr($options['phone_number'] ?? '01635289430'); ?>" class="regular-text" style="width: 100%; margin-bottom: 15px;"><br> <label>Primary Theme Color (Buttons, Icons, Nav Menu)</label><br> <input type="text" name="advaxe_settings[primary_color]" value="<?php echo esc_attr($options['primary_color'] ?? '#00796b'); ?>" class="color-picker"><br><br> <label> <input type="hidden" name="advaxe_settings[is_sticky]" value="0"> <input type="checkbox" name="advaxe_settings[is_sticky]" value="1" <?php checked( 1, $options['is_sticky'] ?? 0 ); ?>> Enable Sticky Header (Desktop & Mobile) </label> </div> </div> <div class="advaxe-card"> <h3><span class="dashicons dashicons-desktop"></span> Desktop Topbar</h3> <div class="card-content"> <label> <input type="hidden" name="advaxe_settings[desktop_top_enable]" value="0"> <input type="checkbox" name="advaxe_settings[desktop_top_enable]" value="1" <?php checked( 1, $options['desktop_top_enable'] ?? 1 ); ?>> <strong>Show Topbar on PC</strong> </label> <br><br> <label>Background Color</label><br> <input type="text" name="advaxe_settings[desktop_top_bg]" value="<?php echo esc_attr($options['desktop_top_bg'] ?? '#fafafa'); ?>" class="color-picker"><br><br> <label>Left Content (HTML/CSS Allowed)</label> <textarea name="advaxe_settings[top_left]"><?php echo wp_unslash($options['top_left'] ?? 'Ecommerce.mohasagorit.solutions'); ?></textarea> <label>Center Content (HTML/CSS Allowed)</label> <textarea name="advaxe_settings[top_center]"><?php echo wp_unslash($options['top_center'] ?? ''); ?></textarea> <label>Right Content (HTML/CSS Allowed)</label> <textarea name="advaxe_settings[top_right]"><?php echo wp_unslash($options['top_right'] ?? '<span style="color:#555; font-weight:bold;">Offer: Free Shipping!</span>'); ?></textarea> </div> </div> <div class="advaxe-card"> <h3><span class="dashicons dashicons-smartphone"></span> Mobile Topbar</h3> <div class="card-content"> <label> <input type="hidden" name="advaxe_settings[mobile_top_enable]" value="0"> <input type="checkbox" name="advaxe_settings[mobile_top_enable]" value="1" <?php checked( 1, $options['mobile_top_enable'] ?? 0 ); ?>> <strong>Show Topbar on Mobile</strong> </label> <br><br> <label>Background Color</label><br> <input type="text" name="advaxe_settings[mobile_top_bg]" value="<?php echo esc_attr($options['mobile_top_bg'] ?? '#005f63'); ?>" class="color-picker"><br><br> <label>Mobile Topbar Content (HTML/CSS Allowed)</label> <textarea name="advaxe_settings[mobile_top_content]"><?php echo wp_unslash($options['mobile_top_content'] ?? '<span style="color:#fff;">Welcome to our shop!</span>'); ?></textarea> </div> </div> </div> <div style="margin-top: 20px;"> <?php submit_button('Save All Changes', 'primary large'); ?> </div> </form> </div> <style> .advaxe-admin-wrap { background: #f0f2f5; padding: 20px; border-radius: 8px; } .advaxe-admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 20px; } .advaxe-card { background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); border: 1px solid #e1e4e8; } .advaxe-card h3 { margin-top: 0; padding-bottom: 10px; border-bottom: 1px solid #eee; display: flex; align-items: center; gap: 8px; color: #1d2327; } .advaxe-card label { font-weight: 600; display: block; margin-bottom: 5px; color: #50575e; } .card-content textarea { width: 100%; height: 80px; margin-bottom: 15px; border-radius: 4px; border: 1px solid #ccc; font-family: monospace; } .upload-flex { display: flex; gap: 10px; margin-bottom: 10px; } .logo-preview-box { background: #f9f9f9; padding: 10px; border: 1px dashed #ccc; border-radius: 4px; text-align: center; } .wp-picker-container { display: block; margin-top: 5px; } </style> <script> jQuery(document).ready(function($){ $('.color-picker').wpColorPicker(); $('#advaxe_upload_btn').click(function(e) { e.preventDefault(); var image = wp.media({ title: 'Select Logo', multiple: false }).open().on('select', function(e){ var uploaded_image = image.state().get('selection').first(); var image_url = uploaded_image.toJSON().url; $('#advaxe_logo_url').val(image_url); $('#advaxe_logo_preview').html('<img src="'+image_url+'" style="max-height: 50px;">'); }); }); }); </script> <?php } /** * 5. Frontend Header Rendering */ function advaxe_render_header() { if ( ! class_exists( 'WooCommerce' ) ) return; $options = get_option( 'advaxe_settings', array() ); $logo_url = $options['logo_url'] ?? ''; $sticky_class = ($options['is_sticky'] ?? 0) == 1 ? 'is-sticky' : ''; $phone_number = $options['phone_number'] ?? '01635289430'; $primary_color = (!empty($options['primary_color'])) ? $options['primary_color'] : '#00796b'; // Dynamic Links $account_link = function_exists('wc_get_page_permalink') ? wc_get_page_permalink( 'myaccount' ) : '#'; $shop_link = function_exists('wc_get_page_permalink') ? wc_get_page_permalink( 'shop' ) : home_url('/shop'); // Dynamic Account Details $account_title = 'Hi,'; $account_name = 'Login/Signup'; if ( is_user_logged_in() ) { $current_user = wp_get_current_user(); $billing_first_name = get_user_meta( $current_user->ID, 'billing_first_name', true ); $account_title = 'Welcome,'; $account_name = ! empty( $billing_first_name ) ? $billing_first_name : 'User'; } ?> <div class="advaxe-header-wrapper <?php echo $sticky_class; ?>"> <div class="advaxe-desktop-header"> <?php if(($options['desktop_top_enable'] ?? 1) == 1): ?> <div class="advaxe-topbar" style="background-color: <?php echo esc_attr($options['desktop_top_bg'] ?? '#fafafa'); ?>;"> <div class="advaxe-container"> <div class="topbar-left"><?php echo do_shortcode(wp_unslash($options['top_left'] ?? '')); ?></div> <div class="topbar-center"><?php echo do_shortcode(wp_unslash($options['top_center'] ?? '')); ?></div> <div class="topbar-right"><?php echo do_shortcode(wp_unslash($options['top_right'] ?? '')); ?></div> </div> </div> <?php endif; ?> <div class="advaxe-main-desktop"> <div class="advaxe-container"> <div class="desktop-logo"> <a href="<?php echo home_url(); ?>"> <?php if($logo_url): ?> <img src="<?php echo esc_url($logo_url); ?>" alt="<?php bloginfo('name'); ?>"> <?php else: ?> <h2 class="site-title" style="color: <?php echo esc_attr($primary_color); ?>;">MOHASAGOR IT <span style="color:#e65100">Solutions</span></h2> <?php endif; ?> </a> </div> <div class="desktop-search"> <form role="search" method="get" class="woocommerce-product-search" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <input type="search" placeholder="Search products..." value="<?php echo get_search_query(); ?>" name="s" /> <input type="hidden" name="post_type" value="product" /> <button type="submit"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg> </button> </form> </div> <div class="desktop-actions"> <div class="action-item call-us"> <a href="tel:<?php echo esc_attr($phone_number); ?>"> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="<?php echo esc_attr($primary_color); ?>" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg> <div><span>Call Us Now:</span><strong><?php echo esc_html($phone_number); ?></strong></div> </a> </div> <!-- Shop Button (Track/Wishlist রিমুভ করে শুধু এটি রাখা হয়েছে) --> <div class="action-item shop-button"> <a href="<?php echo esc_url($shop_link); ?>"> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="<?php echo esc_attr($primary_color); ?>" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path><line x1="3" y1="6" x2="21" y2="6"></line><path d="M16 10a4 4 0 0 1-8 0"></path></svg> <div><span>Visit Our</span><strong>Shop</strong></div> </a> </div> <div class="action-item account"> <a href="<?php echo esc_url($account_link); ?>"> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="<?php echo esc_attr($primary_color); ?>" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg> <div><span><?php echo esc_html($account_title); ?></span><strong><?php echo esc_html($account_name); ?></strong></div> </a> </div> </div> </div> </div> <div class="advaxe-bottom-nav"> <div class="advaxe-container"> <ul class="desktop-nav-list"> <?php advaxe_get_product_categories(); ?> </ul> </div> </div> </div> <div class="advaxe-mobile-header"> <?php if(($options['mobile_top_enable'] ?? 0) == 1): ?> <div class="advaxe-mobile-topbar" style="background-color: <?php echo esc_attr($options['mobile_top_bg'] ?? '#005f63'); ?>;"> <?php echo do_shortcode(wp_unslash($options['mobile_top_content'] ?? '')); ?> </div> <?php endif; ?> <header class="advaxe-header"> <div class="advaxe-container"> <div class="advaxe-left"> <button id="advaxe-menu-trigger" aria-label="Menu"> <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="<?php echo esc_attr($primary_color); ?>" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> <line x1="3" y1="12" x2="21" y2="12"></line> <line x1="3" y1="6" x2="21" y2="6"></line> <line x1="3" y1="18" x2="21" y2="18"></line> </svg> </button> </div> <div class="advaxe-center"> <a href="<?php echo home_url(); ?>"> <?php if($logo_url): ?> <img src="<?php echo esc_url($logo_url); ?>" alt="<?php bloginfo('name'); ?>"> <?php else: ?> <h2 class="site-title" style="color: <?php echo esc_attr($primary_color); ?>;">MOHASAGOR IT <span style="color:#e65100">Solutions</span></h2> <?php endif; ?> </a> </div> <div class="advaxe-right"> <button id="advaxe-search-trigger" aria-label="Search"> <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="<?php echo esc_attr($primary_color); ?>" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8"></circle> <line x1="21" y1="21" x2="16.65" y2="16.65"></line> </svg> </button> </div> </div> <div id="advaxe-search-box" class="advaxe-search-wrapper"> <form role="search" method="get" class="woocommerce-product-search" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <div class="search-inner"> <input type="search" class="search-field" placeholder="Search products..." value="<?php echo get_search_query(); ?>" name="s" /> <input type="hidden" name="post_type" value="product" /> <button type="submit"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg> </button> </div> </form> </div> </header> </div> </div> <div id="advaxe-overlay" class="advaxe-overlay"></div> <div id="advaxe-sidebar" class="advaxe-sidebar"> <div class="advaxe-sidebar-header"> <div class="sidebar-logo"> <?php if($logo_url): ?> <img src="<?php echo esc_url($logo_url); ?>" alt="Logo"> <?php else: ?> <h3>Categories</h3> <?php endif; ?> </div> <button id="advaxe-close-sidebar">×</button> </div> <div class="advaxe-sidebar-content"> <ul class="advaxe-cat-list"> <?php advaxe_get_product_categories(); ?> </ul> </div> </div> <style> /* ========================================= GENERAL & LAYOUT ========================================= */ .advaxe-header-wrapper { width: 100%; background: #fff; z-index: 9999; box-shadow: 0 2px 10px rgba(0,0,0,0.05); position: relative; } .advaxe-header-wrapper.is-sticky { position: -webkit-sticky; position: sticky; top: 0; } .advaxe-container { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 15px; box-sizing: border-box; } /* Responsive Visibility */ .advaxe-desktop-header { display: none; } .advaxe-mobile-header { display: block; } @media (min-width: 992px) { .advaxe-desktop-header { display: block; } .advaxe-mobile-header { display: none; } } /* ========================================= DESKTOP STYLES ========================================= */ .advaxe-topbar { padding: 8px 0; font-size: 13px; color: #555; } .advaxe-topbar .advaxe-container { display: flex; justify-content: space-between; align-items: center; } .topbar-left, .topbar-right, .topbar-center { flex: 1; } .topbar-center { text-align: center; } .topbar-right { text-align: right; } .advaxe-main-desktop { padding: 20px 0; background: #fff; } .advaxe-main-desktop .advaxe-container { display: flex; align-items: center; justify-content: space-between; gap: 30px; } .desktop-logo img { max-height: 50px; width: auto; display: block; } .desktop-logo .site-title { font-size: 22px; font-weight: 700; margin: 0; } .desktop-search { flex: 1; max-width: 600px; } .desktop-search form { display: flex; border: 1px solid <?php echo esc_attr($primary_color); ?>; border-radius: 4px; overflow: hidden; background: #fff; } .desktop-search input[type="search"] { flex: 1; padding: 12px 15px; border: none; outline: none; font-size: 15px; } .desktop-search button { background: <?php echo esc_attr($primary_color); ?>; color: #fff; border: none; padding: 0 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.3s; } .desktop-search button:hover { opacity: 0.9; } .desktop-actions { display: flex; align-items: center; gap: 25px; } .action-item { font-size: 12px; color: #666; cursor: pointer; } .action-item a { display: flex; align-items: center; gap: 10px; color: inherit; text-decoration: none; } .action-item strong { display: block; font-size: 14px; color: #333; font-weight: 600; margin-top: 2px;} .advaxe-bottom-nav { background: <?php echo esc_attr($primary_color); ?>; } ul.desktop-nav-list { list-style: none; padding: 0; margin: 0; display: flex; align-items: center; justify-content: center; gap: 25px; } ul.desktop-nav-list > li > a { color: #fff; text-decoration: none; font-size: 14px; font-weight: 600; padding: 15px 0; display: block; text-transform: uppercase; } ul.desktop-nav-list > li > a:hover { color: #b2dfdb; } ul.desktop-nav-list .cat-toggle { display: none; } ul.desktop-nav-list .children { display: none; position: absolute; top: 100%; left: 0; background: #fff; box-shadow: 0 8px 20px rgba(0,0,0,0.1); z-index: 100; min-width: 220px; border-top: 3px solid <?php echo esc_attr($primary_color); ?>; border-radius: 0 0 4px 4px; padding: 0; } ul.desktop-nav-list > li { position: relative; } ul.desktop-nav-list > li:hover .children { display: block; } ul.desktop-nav-list .children li a { padding: 12px 15px; display: block; color: #444; border-bottom: 1px solid #f1f1f1; text-decoration: none; font-size: 14px; text-transform: capitalize; } ul.desktop-nav-list .children li:last-child a { border-bottom: none; } ul.desktop-nav-list .children li a:hover { color: <?php echo esc_attr($primary_color); ?>; background: #f9f9f9; padding-left: 20px; transition: 0.3s; } /* ========================================= MOBILE STYLES ========================================= */ .advaxe-mobile-topbar { text-align: center; padding: 8px 15px; font-size: 13px; line-height: 1.4; } .advaxe-header { height: 65px; background: #ffffff; display: flex; align-items: center; width: 100%; } .advaxe-mobile-header .advaxe-container { display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 0 15px; } .advaxe-left { flex: 1; display: flex; justify-content: flex-start; } .advaxe-center { flex: 0 0 auto; text-align: center; } .advaxe-right { flex: 1; display: flex; justify-content: flex-end; } .advaxe-left button, .advaxe-right button { background: transparent; border: none; cursor: pointer; padding: 5px; display: flex; align-items: center; } .advaxe-center img { max-height: 40px; width: auto; display: block; margin: 0 auto; } .advaxe-center .site-title { font-size: 18px; font-weight: 700; margin: 0; text-transform: uppercase; line-height: 1.2; } .advaxe-search-wrapper { display: none; position: absolute; top: 100%; left: 0; width: 100%; background: #ffffff; padding: 15px; box-shadow: 0 5px 10px rgba(0,0,0,0.1); border-top: 1px solid #f1f1f1; z-index: 9998; } .advaxe-search-wrapper.show-search { display: block; animation: advaxeFadeIn 0.3s; } .advaxe-search-wrapper .search-inner { display: flex; max-width: 600px; margin: 0 auto; border-radius: 4px; overflow: hidden; border: 1px solid <?php echo esc_attr($primary_color); ?>; } .advaxe-search-wrapper input[type="search"] { flex: 1; padding: 10px 15px; border: none; outline: none; background: #fff; color: #333; } .advaxe-search-wrapper button { background: <?php echo esc_attr($primary_color); ?>; color: #fff; border: none; padding: 0 12px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .advaxe-sidebar { position: fixed; top: 0; left: -320px; width: 280px; height: 100%; background: #fff; z-index: 100000; transition: left 0.3s ease; box-shadow: 2px 0 10px rgba(0,0,0,0.1); display: flex; flex-direction: column; } .advaxe-sidebar.active { left: 0; } .advaxe-sidebar-header { padding: 15px; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; background: #f8f9fa; } .advaxe-sidebar-header img { max-height: 30px; } #advaxe-close-sidebar { font-size: 28px; background: none; border: none; cursor: pointer; color: #555; } .advaxe-sidebar-content { flex: 1; overflow-y: auto; } ul.advaxe-cat-list { list-style: none; padding: 0; margin: 0; } ul.advaxe-cat-list li { border-bottom: 1px solid #f1f1f1; position: relative; } ul.advaxe-cat-list li a { display: block; padding: 12px 15px; text-decoration: none; color: #333; font-size: 15px; } ul.advaxe-cat-list li a:hover { background-color: #f9f9f9; color: <?php echo esc_attr($primary_color); ?>; } .cat-toggle { position: absolute; right: 0; top: 0; width: 45px; height: 45px; display: flex; align-items: center; justify-content: center; cursor: pointer; color: #888; font-size: 14px; z-index: 10;} .advaxe-mobile-header .children, .advaxe-sidebar .children { display: none; background-color: #fcfcfc; padding: 0; margin: 0; list-style: none; } .advaxe-mobile-header .children li a, .advaxe-sidebar .children li a { padding-left: 30px; font-size: 14px; color: #555; } li.open > ul.children { display: block; } li.open > .cat-toggle { transform: rotate(180deg); } .advaxe-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 99999; display: none; } .advaxe-overlay.active { display: block; } @keyframes advaxeFadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } </style> <script> document.addEventListener('DOMContentLoaded', function() { // Mobile Search Toggle const searchTrigger = document.getElementById('advaxe-search-trigger'); const searchBox = document.getElementById('advaxe-search-box'); if(searchTrigger && searchBox){ searchTrigger.addEventListener('click', function(e) { e.preventDefault(); searchBox.classList.toggle('show-search'); if(searchBox.classList.contains('show-search')){ const input = searchBox.querySelector('input[type="search"]'); if(input) input.focus(); } }); } // Mobile Sidebar Toggle const menuTrigger = document.getElementById('advaxe-menu-trigger'); const sidebar = document.getElementById('advaxe-sidebar'); const overlay = document.getElementById('advaxe-overlay'); const closeBtn = document.getElementById('advaxe-close-sidebar'); function toggleSidebar() { if(sidebar) sidebar.classList.toggle('active'); if(overlay) overlay.classList.toggle('active'); } if(menuTrigger) menuTrigger.addEventListener('click', toggleSidebar); if(closeBtn) closeBtn.addEventListener('click', toggleSidebar); if(overlay) overlay.addEventListener('click', toggleSidebar); // Sidebar Accordion Logic const toggles = document.querySelectorAll('.cat-toggle'); toggles.forEach(toggle => { toggle.addEventListener('click', function(e) { e.preventDefault(); e.stopPropagation(); this.parentElement.classList.toggle('open'); }); }); // ========================================== // NEW: Open sidebar via custom link // ========================================== document.addEventListener('click', function(e) { const customLink = e.target.closest('a[href="#open-advaxe-sidebar"]'); if (customLink) { e.preventDefault(); if(sidebar) sidebar.classList.add('active'); if(overlay) overlay.classList.add('active'); } }); }); </script> <?php } add_action('wp_body_open', 'advaxe_render_header'); /** * 6. Category Logic (Recursive) */ function advaxe_get_product_categories( $parent_id = 0 ) { if ( ! taxonomy_exists( 'product_cat' ) ) return; $terms = get_terms([ 'taxonomy' => 'product_cat', 'hide_empty' => true, 'parent' => $parent_id, 'orderby' => 'name', ]); if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { foreach ( $terms as $term ) { $children = get_terms([ 'taxonomy' => 'product_cat', 'parent' => $term->term_id, 'hide_empty' => true ]); $has_child = !empty($children) && !is_wp_error($children); echo '<li class="' . ($has_child ? 'has-child' : '') . '">'; echo '<a href="' . esc_url( get_term_link( $term ) ) . '">' . esc_html( $term->name ) . '</a>'; if ( $has_child ) { echo '<span class="cat-toggle">▾</span>'; echo '<ul class="children">'; advaxe_get_product_categories( $term->term_id ); echo '</ul>'; } echo '</li>'; } } }