1. Home
  2. WordPress
  3. Theme Development
  4. custom navwalker

custom navwalker

মনেকরি আমাদের নিচের মতো navbar কোড রয়েছে

    <header class="bg-gradient-to-r from-blue-500 to-purple-600 fixed top-0 left-0 w-full z-50 transition-all duration-300 ease-in-out bg-transparent" id="navbar">
        <nav class="container mx-auto px-4 py-4 flex justify-between items-center">
            <div class="text-2xl font-bold text-white">Logo</div>
            
            
            
            
            
            
            <div class="hidden lg:flex space-x-6">
                <div class="group relative">
                    <a href="#" class="text-white hover:text-gray-300">Home</a>
                </div>
                <div class="group relative">
                    <a href="#" class="text-white hover:text-gray-300">About</a>
                    <div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300">
                        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Our Story</a>
                        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Team</a>
                    </div>
                </div>
                <div class="group relative">
                    <a href="#" class="text-white hover:text-gray-300">Services</a>
                    <div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300">
                        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Web Design</a>
                        <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Development</a>
                        <div class="group/sub relative">
                            <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Marketing</a>
                            <div class="absolute left-full top-0 mt-0 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover/sub:opacity-100 group-hover/sub:visible transition-all duration-300">
                                <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">SEO</a>
                                <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Social Media</a>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="group relative">
                    <a href="#" class="text-white hover:text-gray-300">Contact</a>
                </div>
            </div>
            
            
            
            
            
            
            
            
            
            
            <div class="hidden lg:block">
                <a href="#" class="bg-white text-blue-600 px-6 py-2 rounded-full hover:bg-blue-600 hover:text-white transition-colors duration-300">Contact Us</a>
            </div>
            <button id="menuToggle" class="lg:hidden text-black focus:outline-none bg-white rounded p-2">
                <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
                </svg>
            </button>
            
        </nav>
    </header>

আমার navbar তিনটি এরিয়া আছে যার মধ্যে আমরা শুধু মাঝের অংশ নিয়ে কাজ করবো

আমরা আমাদের হেডার সেকশন এ নিচের কোড লিখবো মাঝের অংশ ছাড়া


	<header class="bg-gradient-to-r from-blue-500 to-purple-600 fixed top-0 left-0 w-full z-50 transition-all duration-300 ease-in-out bg-transparent" id="navbar">
    <nav class="container mx-auto px-4 py-4 flex justify-between items-center">
        <div class="text-2xl font-bold text-white">Logo</div>

        <!-- Display dynamic menu here -->


        <div class="hidden lg:block">
            <a href="#" class="bg-white text-blue-600 px-6 py-2 rounded-full hover:bg-blue-600 hover:text-white transition-colors duration-300">Contact Us</a>
        </div>

        <button id="menuToggle" class="lg:hidden text-black focus:outline-none bg-white rounded p-2">
            <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
            </svg>
        </button>
    </nav>
</header>

মেনু টি দেখতে নিচের মতো দেখাবে

এবার আমি functions.php তে মেনু রেজিস্টার করি

	function register_my_menus() {
		register_nav_menus(
			array(
				'header-menu' => __('Header Menu'),
			)
		);
	}
	add_action('init', 'register_my_menus');

একটি মেনু বানাই ওয়ার্ডপ্রেস এ অ্যাডমিন প্যানেল থেকে

থিমের হেডার ফাইলে নিচের কোড দেই

        <!-- Display dynamic menu here -->
        <?php
        wp_nav_menu(array(
            'theme_location' => 'header-menu',
            'container' => false,
            'menu_class' => 'hidden lg:flex space-x-6',
            'walker' => new Custom_Nav_Walker(),
			'items_wrap' => '<div class="hidden lg:flex space-x-6">%3$s</div>', // This adds the div wrapper instead of ul

        ));
        ?>

আমরা আমাদের মেনুতে ul নেবো না এজন্য items_wrap ব্যবহার করেছি

আমরা একটা কাস্টম walker ক্লাস ব্যবহার করেছি ঐটা functions.php তে যোগ করি

class Custom_Nav_Walker extends Walker_Nav_Menu {

    // মেনু আইটেমের আউটপুট শুরু করার জন্য ফাংশন
    function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
        // গভীরতার (depth) উপর ভিত্তি করে ইনডেন্টেশন তৈরি করা
        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        // মেনু আইটেমের ক্লাস সংগ্রহ করা
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));

        // লিংক অ্যাট্রিবিউট সেট করা (যেমন href, class)
        $atts = array();
        $atts['href'] = !empty($item->url) ? $item->url : ''; // লিংকের URL সেট করা
        $atts['class'] = 'text-white hover:text-gray-300'; // লিংকের CSS ক্লাস যোগ করা
        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args);

        // লিংক ট্যাগের অ্যাট্রিবিউট তৈরি করা
        $attributes = '';
        foreach ($atts as $attr => $value) {
            if (!empty($value)) {
                $attributes .= ' ' . $attr . '="' . esc_attr($value) . '"';
            }
        }

        // আউটপুট তৈরি করা, শুরুতে <div> এবং শেষে <a> ট্যাগের সাথে আউটপুট
        $item_output = $args->before;
        
        // এখানে <div> যোগ করা হচ্ছে
        $item_output .= '<div class="group relative">';

        // লিংক ট্যাগ যোগ করা
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= '</a>'; // লিংক ট্যাগ বন্ধ

        // এখানে <div> ট্যাগ বন্ধ করা হচ্ছে
        $item_output .= '</div>';

        $item_output .= $args->after;

        // তৈরি করা আউটপুট মূল আউটপুটের সাথে যোগ করা
        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }

    // মেনু আইটেমের আউটপুট শেষ করার জন্য ফাংশন
    function end_el(&$output, $item, $depth = 0, $args = null) {
        // এখানে কিছু করার প্রয়োজন নেই, কারণ <div> এবং <a> ট্যাগ ইতিমধ্যে আগেই বন্ধ করা হয়েছে।
    }
}

আমাদের মেনু গুলো নিচের মতো করে হবে

                <div class="group relative">
                    <a href="#" class="text-white hover:text-gray-300">Home</a>
                </div>


এজন্য আমরা ৩ ০ নং লাইনে div ও তার ক্লাস যুক্ত করেছি এবং এর ভিতরে থাকা a গুলোর ক্লাস হবে text-white hover:text-gray-300 যা ১ ৬ নং লাইনে বলে দিয়েছি

আমার মেনু টি এখন নিচের মতো

এবার আমাদের সাবমেনু নিয়ে কাজ করতে হবে এজন্য আমাদের কোড এ কয়েকটি কোড যোগ করতে হবে তার আগে আমরা আমাদের সাবমেনু এর স্ট্রাকচার দেখি

  <div class="group relative">
      <a href="#" class="text-white hover:text-gray-300">About</a>
      
          <!-- সাব মেনু শুরু  -->

      <div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300">
          <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Our Story</a>
          <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Team</a>
      </div>
      
       <!-- সাব মেনু শেষ -->
  </div>

এবার আমাদের আগের navwalker ক্লাস এ নিচের কোড গুলো যুক্ত করতে হবে

সাবমেনু আছে কিনা চেক করার জন্য কোড যোগ করা হয়েছে:

$has_children = in_array('menu-item-has-children', $classes);

মূল মেনু ও সাবমেনুর জন্য আলাদা CSS ক্লাস যুক্ত করা হয়েছে:

$atts['class'] = $depth === 0 ? 'text-white hover:text-gray-300' : 'block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100';

সাবমেনুর জন্য অতিরিক্ত div ট্যাগ যুক্ত করা হয়েছে:

if ($has_children) {
    $item_output .= '<div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300">';
}

মূল মেনুর জন্য div ট্যাগ যুক্ত করা হয়েছে:

$item_output .= '<div class="group relative">';

সাবমেনুর div ট্যাগ বন্ধ করা হয়েছে:

if (in_array('menu-item-has-children', $item->classes)) {
    $output .= "</div>"; // সাবমেনুর <div> বন্ধ
}

আগের কোড:

class Custom_Nav_Walker extends Walker_Nav_Menu {

    // মেনু আইটেমের আউটপুট শুরু করার জন্য ফাংশন
    function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
        // গভীরতার (depth) উপর ভিত্তি করে ইনডেন্টেশন তৈরি করা
        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        // মেনু আইটেমের ক্লাস সংগ্রহ করা
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));

        // লিংক অ্যাট্রিবিউট সেট করা (যেমন href, class)
        $atts = array();
        $atts['href'] = !empty($item->url) ? $item->url : ''; // লিংকের URL সেট করা
        $atts['class'] = 'text-white hover:text-gray-300'; // লিংকের CSS ক্লাস যোগ করা
        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args);

        // লিংক ট্যাগের অ্যাট্রিবিউট তৈরি করা
        $attributes = '';
        foreach ($atts as $attr => $value) {
            if (!empty($value)) {
                $attributes .= ' ' . $attr . '="' . esc_attr($value) . '"';
            }
        }

        // আউটপুট তৈরি করা, শুরুতে <div> এবং শেষে <a> ট্যাগের সাথে আউটপুট
        $item_output = $args->before;

        // এখানে <div> যোগ করা হচ্ছে
        $item_output .= '<div class="group relative">';

        // লিংক ট্যাগ যোগ করা
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= '</a>'; // লিংক ট্যাগ বন্ধ

        // এখানে <div> ট্যাগ বন্ধ করা হচ্ছে
        $item_output .= '</div>';

        $item_output .= $args->after;

        // তৈরি করা আউটপুট মূল আউটপুটের সাথে যোগ করা
        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }

    // মেনু আইটেমের আউটপুট শেষ করার জন্য ফাংশন
    function end_el(&$output, $item, $depth = 0, $args = null) {
        // এখানে কিছু করার প্রয়োজন নেই, কারণ <div> এবং <a> ট্যাগ ইতিমধ্যে আগেই বন্ধ করা হয়েছে।
    }
}
class Custom_Nav_Walker extends Walker_Nav_Menu {

    // মেনু আইটেমের আউটপুট শুরু করার জন্য ফাংশন
    function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) {
        // গভীরতার (depth) উপর ভিত্তি করে ইনডেন্টেশন তৈরি করা
        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        // মেনু আইটেমের ক্লাস সংগ্রহ করা
        $classes = empty($item->classes) ? array() : (array) $item->classes;
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));

        // সাবমেনু আছে কিনা চেক করা
        $has_children = in_array('menu-item-has-children', $classes);  // **// নতুন**

        // লিংক অ্যাট্রিবিউট সেট করা (যেমন href, class)
        $atts = array();
        $atts['href'] = !empty($item->url) ? $item->url : ''; // লিংকের URL সেট করা
        $atts['class'] = $depth === 0 ? 'text-white hover:text-gray-300' : 'block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100'; // মূল মেনু ও সাবমেনুর জন্য আলাদা ক্লাস  **// নতুন**
        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args);

        // লিংক ট্যাগের অ্যাট্রিবিউট তৈরি করা
        $attributes = '';
        foreach ($atts as $attr => $value) {
            if (!empty($value)) {
                $attributes .= ' ' . $attr . '="' . esc_attr($value) . '"';
            }
        }

        // আউটপুট তৈরি করা, শুরুতে <div> এবং <a> ট্যাগের সাথে আউটপুট
        $item_output = $args->before;

        // মূল মেনুর জন্য <div> যোগ করা
        $item_output .= '<div class="group relative">';  // **// নতুন**

        // লিংক ট্যাগ যোগ করা
        $item_output .= '<a'. $attributes .'>'; 
        $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
        $item_output .= '</a>'; // লিংক ট্যাগ বন্ধ

        // সাবমেনুর জন্য <div> যোগ করা (যদি সাবমেনু থাকে)
        if ($has_children) {  // **// নতুন**
            $item_output .= '<div class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300">';  // **// নতুন**
        }

        $item_output .= $args->after;

        // তৈরি করা আউটপুট মূল আউটপুটের সাথে যোগ করা
        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }

    // মেনু আইটেমের আউটপুট শেষ করার জন্য ফাংশন
    function end_el(&$output, $item, $depth = 0, $args = null) {
        // সাবমেনুর <div> বন্ধ করা (যদি সাবমেনু থাকে)
        if (in_array('menu-item-has-children', $item->classes)) {  // **// নতুন**
            $output .= "</div>"; // সাবমেনুর <div> বন্ধ  **// নতুন**
        }
        $output .= "</div>\n"; // মেনু আইটেমের মূল <div> বন্ধ
    }
}

মার্ক করা নতুন অংশগুলো:

  • সাবমেনু আছে কিনা চেক করার জন্য has_children ভ্যারিয়েবল যোগ করা হয়েছে।
  • মেনু এবং সাবমেনুর CSS ক্লাস আলাদা করার জন্য atts['class'] যুক্ত করা হয়েছে।
  • সাবমেনু থাকলে অতিরিক্ত div যুক্ত করার জন্য কোড যোগ করা হয়েছে।
  • সাবমেনুর div বন্ধ করার জন্য end_el ফাংশনে কোড যোগ করা হয়েছে।

How can we help?