پنج سال پیش، منوی یک سایت شرکتی را با یک حلقه سفارشی و آرایه دستی ساختم. سه ماه بعد، مدیر محتوا آمد و گفت می‌خواهد یک آیتم به منو اضافه کند؛ من باید در کد دست می‌بردم و هر بار تغییر را روی سرور آپلود می‌کردم. آن روز فهمیدم چرا وردپرس از سال ۲۰۱۰ سیستم منوی رسمی دارد: منو، داده است؛ نه کد. این درس، تا امروز در هر پروژه‌ای به کارم آمده.

سیستم منوی وردپرس، ساختاری داده‌ای دارد که در جداول اختصاصی ذخیره می‌شود و از طریق پیشخوان قابل مدیریت است. اما در پروژه‌های حرفه‌ای، اغلب نیاز به کنترل برنامه‌نویسی‌شده داریم: ساخت منو در زمان نصب، افزودن آیتم پویا، یا تغییر منو بر اساس شرط. اینجاست که توابع منو وارد می‌شوند. اگر با مفهوم توابع وردپرس آشنایی کلی ندارید، نحوه استفاده از توابع وردپرس در پروژه‌ها پیش‌نیاز این مقاله است.

ثبت منو در قالب

اولین گام، ثبت موقعیت‌های منو در قالب است. در فایل functions.php قالب یا چایلد تم:

add_action( "after_setup_theme", function() {
    register_nav_menus( array(
        "primary" => "منوی اصلی",
        "footer"  => "منوی فوتر",
        "mobile"  => "منوی موبایل",
    ) );
} );

این تابع، موقعیت‌های منو را در پیشخوان ← نمایش ← فهرست‌ها قابل‌اختصاص می‌کند. راهنمای کامل این بخش در ساختار فایل‌های قالب استاندارد و توسعه قالب وردپرس از صفر آمده است. توصیه عملی من: حتی اگر امروز فقط یک منو نیاز دارید، دو موقعیت ثبت کنید. اضافه‌کردن موقعیت در ماه ششم، ساده است؛ ولی تغییر ساختار قالب در همان زمان، هزینه دارد.

نمایش منو در قالب

سه تابع اصلی برای نمایش:

// روش مدرن
wp_nav_menu( array(
    "theme_location"  => "primary",
    "container"       => "nav",
    "container_class" => "main-navigation",
    "menu_class"      => "menu",
    "fallback_cb"     => false,
) );

پارامتر fallback_cb = false، از نمایش لیست پیش‌فرض برگه‌ها وقتی منویی اختصاص داده نشده جلوگیری می‌کند. برای منوهای ساده، wp_page_menu هم کاربرد دارد، ولی wp_nav_menu استاندارد مدرن است. برای افزودن کلاس یا ویژگی به آیتم‌های منو، از فیلتر nav_menu_link_attributes استفاده کنید:

add_filter( "nav_menu_link_attributes", function( $atts, $item, $args ) {
    if ( "primary" === $args->theme_location && in_array( "menu-item-has-children", $item->classes, true ) ) {
        $atts["aria-haspopup"] = "true";
    }
    return $atts;
}, 10, 3 );

این نوع سفارشی‌سازی، برای دسترس‌پذیری و سئو مهم است. راهنمای دسترس‌پذیری در استانداردهای دسترس‌پذیری وب.

ساخت منو با کد

گاهی نیاز داریم منو را در زمان فعال‌سازی افزونه یا قالب بسازیم:

function myplugin_create_default_menu() {
    $menu_name = "منوی اصلی";
    $menu_exists = wp_get_nav_menu_object( $menu_name );
    
    if ( ! $menu_exists ) {
        $menu_id = wp_create_nav_menu( $menu_name );
        
        wp_update_nav_menu_item( $menu_id, 0, array(
            "menu-item-title"  => "خانه",
            "menu-item-url"    => home_url( "/" ),
            "menu-item-status" => "publish",
        ) );
        
        wp_update_nav_menu_item( $menu_id, 0, array(
            "menu-item-title"  => "درباره ما",
            "menu-item-url"    => home_url( "/about/" ),
            "menu-item-status" => "publish",
        ) );
    }
}
add_action( "after_switch_theme", "myplugin_create_default_menu" );

توابع کلیدی: wp_create_nav_menu، wp_update_nav_menu_item، wp_get_nav_menu_object. نکته حیاتی: اگر منو وجود دارد، دوباره نسازید — این باگ در پروژه‌های تازه‌کار شایع است و نتیجه‌اش چندین منوی تکراری در پیشخوان است که مدیر محتوا را گیج می‌کند. همیشه با wp_get_nav_menu_object وجود را بررسی کنید.

افزودن آیتم پویا به منو

گاهی نیاز داریم یک آیتم پویا — مثلاً لینک به آخرین نوشته — به منو اضافه کنیم. با فیلتر wp_nav_menu_items:

add_filter( "wp_nav_menu_items", function( $items, $args ) {
    if ( "primary" !== $args->theme_location ) {
        return $items;
    }
    
    $latest = get_posts( array( "numberposts" => 1 ) );
    if ( ! empty( $latest ) ) {
        $items .= sprintf(
            "<li class="menu-item"><a href="%s">آخرین مطلب: %s</a></li>",
            esc_url( get_permalink( $latest[0] ) ),
            esc_html( get_the_title( $latest[0] ) )
        );
    }
    return $items;
}, 10, 2 );

این الگو، در سایت‌های خبری و مجله‌ای کاربرد دارد. نکته مهم: همیشه esc_url و esc_html را رعایت کنید — آیتم پویا، یک نقطه ورود بالقوه برای XSS است. راهنمای امنیت در PHP امن در وردپرس و پاک‌سازی داده‌ها.

فیلتر بر اساس نقش کاربر

گاهی می‌خواهیم آیتم خاصی فقط برای کاربران لاگین‌شده نمایش داده شود:

add_filter( "wp_nav_menu_objects", function( $items, $args ) {
    if ( is_user_logged_in() ) {
        return $items;
    }
    
    foreach ( $items as $key => $item ) {
        if ( in_array( "logged-in-only", $item->classes, true ) ) {
            unset( $items[ $key ] );
        }
    }
    return $items;
}, 10, 2 );

این کار، با افزودن کلاس logged-in-only به آیتم در پیشخوان — از بخش «کلاس CSS» که باید در «گزینه‌های نمایش» فعال شود — انجام می‌شود. کاربردش: نمایش لینک «پنل کاربری» فقط برای اعضا. راهنمای نقش‌ها در توابع نقش و دسترسی و کار با User Meta آمده است.

منوی موبایل و دسترس‌پذیری

منوی موبایل، یکی از نقاط حساس در سایت‌های حرفه‌ای است. سه نکته:

  • آیکون همبرگر: باید در همه مرورگرها یکسان عمل کند. استفاده از SVG به‌جای فونت آیکون توصیه می‌شود.
  • دسترس‌پذیری: منو باید با کیبورد قابل باز و بسته شدن باشد. aria-expanded و aria-controls را رعایت کنید.
  • عملکرد در گوشی: زیرمنوها باید با لمس قابل باز شدن باشند، نه با hover. در دستگاه‌های لمسی، hover معنایی ندارد.

راهنمای کامل در قالب ریسپانسیو چیست و ریسپانسیو کردن سایت.

منو و سئو

منو، نقش مهمی در سئو دارد. سه نکته که در پروژه‌های خودم جدی می‌گیرم:

  1. ساختار لینک داخلی: منو، یکی از اصلی‌ترین مسیرهای لینک داخلی است. هر آیتم، یک لینک داخلی محسوب می‌شود و در انتقال اعتبار صفحات نقش دارد.
  2. متن لنگر معنادار: «اینجا کلیک کنید» بد است؛ «خدمات طراحی سایت» خوب است. متن لنگر به گوگل می‌گوید صفحه مقصد درباره چیست.
  3. عمق مناسب: منوهای سه‌سطحی، هم برای کاربر و هم برای خزنده گیج‌کننده‌اند. دو سطح کافی است؛ اگر به سطح سوم نیاز دارید، ساختار دسته‌بندی سایت را بازبینی کنید.

راهنمای سئوی داخلی در سئوی درون‌صفحه و ساختار URL حرفه‌ای. یک تجربه واقعی: در پروژه‌ای، بازطراحی منو — فقط جابه‌جایی آیتم‌ها و تغییر متن لنگرها — نرخ کلیک داخلی را ۳۰ درصد بالا برد، بدون هیچ تغییر محتوایی.

اشتباهات رایج در مدیریت منو

  • ساخت منو در فایل قالب والد: با آپدیت قالب از بین می‌رود. راه‌حل: چایلد تم.
  • نبود بررسی وجود منو پیش از ساخت: باعث ایجاد منوهای تکراری می‌شود. همیشه با wp_get_nav_menu_object چک کنید.
  • استفاده از wp_page_menu به‌جای wp_nav_menu: امکانات سفارشی‌سازی کمتر، ساختار HTML ضعیف‌تر.
  • نبود fallback_cb = false: نمایش خودکار لیست برگه‌ها وقتی منویی اختصاص نیافته — تجربه کاربری بد.
  • نادیده‌گرفتن escape در آیتم‌های پویا: خطر XSS. راهنما در پاک‌سازی داده‌ها.
  • استفاده از hover برای زیرمنو در موبایل: در دستگاه‌های لمسی کار نمی‌کند؛ باید با لمس باز شود.
  • نادیده‌گرفتن تعداد آیتم: منوی با بیست آیتم، در موبایل قابل استفاده نیست. حداکثر هفت آیتم.

جمع‌بندی

توابع منوی وردپرس، سه کاربرد اصلی دارند: ثبت موقعیت، نمایش، و سفارشی‌سازی. سه اصل را در پایان تاکید می‌کنم: اول، منو را داده ببینید نه کد؛ ساخت آن را در زمان نصب با wp_create_nav_menu انجام دهید. دوم، در نمایش از wp_nav_menu با پارامترهای کامل استفاده کنید. سوم، برای سفارشی‌سازی از فیلترهای رسمی مثل wp_nav_menu_items و nav_menu_link_attributes بهره ببرید.

اگر تجربه‌ای از ساخت منوی پویا دارید یا باگی در این مسیر رفع کرده‌اید، در دیدگاه‌ها بنویسید — همان گزارش‌های واقعی، راهنمای بعدی را دقیق‌تر می‌کند. 🧭