چرا منوی شما بدون register_nav_menus قابل مدیریت نیست؟ راهنمای کامل
تابع register_nav_menus برای ثبت مکانهای منو در وردپرس؛ بررسی پارامترها، hook after_setup_theme، پیامهای fallback و اشتباهات رایج در قالب.
چرا ثبت مکان منو اهمیت دارد؟
در قالبهای سنتی، منوها معمولاً بهصورت ثابت در فایل هدر نوشته میشدند. این رویکرد باعث میشد که هر تغییر در منو نیازمند ویرایش کد باشد. وردپرس با معرفی تابعregister_nav_menus() این مشکل را حل کرد: بهجای کدنویسی مستقیم، مکانهای منو در قالب ثبت میشوند و کاربر از پنل مدیریت، آیتمها را مدیریت میکند.
این رویکرد نهتنها تجربه کاربری مدیر سایت را بهتر میکند، بلکه نگهداری قالب را نیز آسانتر میسازد. یک قالب حرفهای معمولاً چندین مکان منو دارد: منوی اصلی، منوی موبایل، منوی فوتر و منوهای ابزارکی. هر یک از این مکانها با register_nav_menus() ثبت میشوند.
تابع register_nav_menus چیست؟
تابعregister_nav_menus() یک تابع هسته وردپرس است که در فایل wp-includes/nav-menu.php تعریف شده است. این تابع یک یا چند مکان منو در قالب ثبت میکند و به وردپرس میگوید که این مکانها در کدام بخش از قالب استفاده میشوند.
نکته مهم این است که این تابع منو را نمایش نمیدهد؛ تنها مکان را ثبت میکند. برای نمایش منو، باید از wp_nav_menu() استفاده کرد که در راهنمای wp_nav_menu به تفصیل بررسی شده است.
هوک after_setup_theme محل استاندارد فراخوانی این تابع است. اگر در هوک دیگری فراخوانی شود، ممکن است مکانهای منو در پنل مدیریت نمایش داده نشوند.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function register_nav_menus( $locations = array() ) {
global $_wp_registered_nav_menus;
// ...
}
پارامتر ورودی یک آرایه انجمنی است که کلیدهای آن، نامک مکان (Location Slug) و مقادیر آن، برچسب نمایشی در پنل مدیریت هستند.
نمونه:
register_nav_menus( array(
'primary' => __( 'منوی اصلی', 'textdomain' ),
'mobile' => __( 'منوی موبایل', 'textdomain' ),
'footer' => __( 'منوی فوتر', 'textdomain' ),
'top-bar' => __( 'منوی نوار بالا', 'textdomain' ),
) );
نامک مکان باید انگلیسی و بدون کاراکتر خاص باشد. برچسب نمایشی از توابع ترجمه مانند __() عبور میکند تا قالب چندزبانه باقی بماند.
هوک صحیح فراخوانی
تابعregister_nav_menus() باید در هوک after_setup_theme فراخوانی شود. اگر در هوک دیگری فراخوانی شود، احتمال بروز رفتار غیرمنتظره وجود دارد.
نمونه صحیح:
add_action( 'after_setup_theme', 'mytheme_register_menus' );
function mytheme_register_menus() {
register_nav_menus( array(
'primary' => __( 'منوی اصلی', 'mytheme' ),
'footer' => __( 'منوی فوتر', 'mytheme' ),
) );
}
نکته مهم: اگر در همان هوک از add_theme_support هم استفاده میکنید، ترتیب فراخوانی مهم نیست، اما بهتر است ابتدا add_theme_support و سپس register_nav_menus فراخوانی شود. برای مطالعه بیشتر به راهنمای add_theme_support مراجعه کنید.
تعریف location و استفاده از آن
نامک هر location (مانندprimary، footer) قراردادی است که در سراسر قالب استفاده میشود. بهتر است نامکها معنادار و کوتاه باشند.
قاعدههای نامگذاری:
- فقط حروف کوچک انگلیسی و خط تیره
- معنادار و گویا (نه menu1 و menu2)
- پایدار در طول زمان
- متفاوت در هر مکان
هر location یک شناسه یکتا است که در wp_nav_menu() با پارامتر theme_location ارجاع داده میشود.
نمونه کامل استفاده در دو طرف:
// ثبت
register_nav_menus( array(
'primary' => __( 'منوی اصلی', 'mytheme' ),
) );
// نمایش
wp_nav_menu( array(
'theme_location' => 'primary',
'container' => 'nav',
'menu_class' => 'main-menu',
) );
اتصال منو به مکان در پیشخوان
پس از ثبت مکانها، در پیشخوان وردپرس در بخش «نمایش > فهرستها»، کاربر میتواند یک منو بسازد و آن را به یکی از مکانهای ثبتشده اختصاص دهد. این اتصال در پایگاه داده ذخیره میشود و در فرانتاند، وردپرس بر پایه آن تصمیم میگیرد کدام منو در کدام مکان نمایش داده شود. نکته مهم این است که اگر کاربر منویی به یک مکان اختصاص نداده باشد، وردپرس ممکن است اولین منوی موجود را نمایش دهد یا پیام پیشفرض نشان دهد. برای کنترل دقیق این رفتار، باید از پارامترfallback_cb در wp_nav_menu استفاده کرد.
کاربردهای عملی در قالب
نمونه استفاده در هدر:<header class="site-header">
<?php
wp_nav_menu( array(
'theme_location' => 'primary',
'container' => 'nav',
'container_class' => 'main-navigation',
'menu_class' => 'primary-menu',
'depth' => 2,
'fallback_cb' => false,
) );
?>
</header>
نمونه استفاده در فوتر:
<footer class="site-footer">
<?php
wp_nav_menu( array(
'theme_location' => 'footer',
'container' => false,
'menu_class' => 'footer-menu',
'depth' => 1,
) );
?>
</footer>
نکته مهم: پارامتر depth عمق منو را کنترل میکند. برای منوی فوتر که معمولاً یکسطحی است، depth را ۱ قرار دهید. برای منوی اصلی، ۲ یا ۳ مناسب است.
نقش در Child Theme
در Child Theme، تابعregister_nav_menus را میتوان دوباره در functions.php فراخوانی کرد تا مکانهای جدید اضافه شوند. اما توجه داشته باشید که مکانهای ثبتشده در Parent Theme از بین نمیروند و فقط مکانهای جدید اضافه میشوند.
الگوی افزودن مکان جدید:
add_action( 'after_setup_theme', 'mychild_register_extra_menus', 20 );
function mychild_register_extra_menus() {
register_nav_menus( array(
'sidebar-menu' => __( 'منوی سایدبار', 'mychild' ),
) );
}
نکته مهم: اولویت ۲۰ باعث میشود این تابع بعد از تابع والد اجرا شود. برای مطالعه بیشتر درباره ساختار Child Theme به راهنمای get_stylesheet_directory و راهنمای get_template_directory مراجعه کنید.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبود هوک درست است. اگر این تابع درinit یا wp_loaded فراخوانی شود، ممکن است مکانهای منو در پنل مدیریت نمایش داده نشوند.
اشتباه دوم، نبود نامک معنادار است. نامکهایی مانند menu1، menu2 و my-menu پایداری لازم را ندارند. از نامک معنادار مانند primary، footer و mobile استفاده کنید.
اشتباه سوم، نبود fallback است. اگر کاربری منویی به مکان اختصاص نداده باشد، باید رفتار مناسب تعریف شود. با پارامتر fallback_cb در wp_nav_menu میتوان رفتار پیشفرض را تعیین کرد.
اشتباه چهارم، نبود شرط برای بررسی ثبت منو است. در افزونهها، اگر قالب منویی ثبت نکرده باشد، باید از خطا جلوگیری کرد.
اشتباه پنجم، نبود تست است. باید منو را در همه مکانها و با آیتمهای مختلف تست کنید.
اشتباه ششم، نبود ترجمه در برچسبها است. برچسبهای نمایشی در پنل مدیریت باید از توابع ترجمه عبور کنند.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعregister_nav_menus() یک نقطه معماری در لایه قالب است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه ثبت مکان است. این تابع مکانها را در آرایه جهانی $_wp_registered_nav_menus ذخیره میکند که در طول درخواست HTTP باقی میماند و مبنای تصمیمگیری سایر بخشهای هسته وردپرس است.
لایه دوم لایه اتصال است. مکانهای ثبتشده در پنل مدیریت به کاربر نمایش داده میشوند و او میتواند منوها را به این مکانها اختصاص دهد. این اتصال در جدول wp_term_relationships و wp_options ذخیره میشود و در زمان نمایش فرانتاند مورد استفاده قرار میگیرد.
لایه سوم لایه امنیت است. اگر مکانها بهدرستی ثبت نشوند یا fallback نامناسب تعریف شود، ممکن است دادههای نامناسب در فرانتاند نمایش داده شوند. همیشه از پارامترهای امنیتی مناسب استفاده کنید.
لایه چهارم لایه کشینگ است. نتیجه ثبت مکانها معمولاً کش نمیشود، اما ساختار HTML نهایی ممکن است کش شود. اگر منو بر اساس وضعیت کاربر تغییر میکند، باید استراتژی کش مناسب انتخاب شود.
لایه پنجم لایه Multisite است. در شبکههای Multisite، هر سایت میتواند منوهای متفاوتی داشته باشد. تابع register_nav_menus در هر سایت جداگانه فراخوانی میشود.
لایه ششم لایه Performance است. تعداد زیاد مکانهای منو تأثیر محسوسی روی سرعت ندارد، اما اگر هر مکان منوی طولانی داشته باشد، اندازه HTML افزایش مییابد.
لایه هفتم لایه Accessibility است. ساختار منو باید با استانداردهای دسترسیپذیری سازگار باشد. استفاده از تگ nav و برچسب مناسب (aria-label) توصیه میشود.
لایه هشتم لایه تست است. تستهای End-to-End باید مطمئن شوند که منوها در همه مکانها بهدرستی نمایش داده میشوند. مفاهیم پایهای منو در Menu در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای wp_nav_menu، راهنمای register_widget، راهنمای wp_get_theme، راهنمای get_header و راهنمای get_footer مراجعه کنید.
پرسشهای پرتکرار
در کدام هوک باید register_nav_menus را فراخوانی کرد؟ در هوکafter_setup_theme.
آیا میتوان چند بار این تابع را فراخوانی کرد؟ بله، اما بهتر است همه مکانها در یک فراخوانی ثبت شوند.
تفاوت register_nav_menus و wp_nav_menu چیست؟ اولی مکان منو را ثبت میکند و دومی منو را نمایش میدهد.
آیا در Child Theme باید مکانها را دوباره ثبت کرد؟ خیر، مکانهای Parent Theme بهارث میرسند. فقط مکانهای جدید را اضافه کنید.
چطور منو را در قالب نمایش دهیم؟ با wp_nav_menu و پارامتر theme_location.
نتیجه و مسیر ادامه
تابعregister_nav_menus() نقطه اتصال قالب به سیستم مدیریت منو در وردپرس است. استفاده درست از آن یعنی فراخوانی در هوک صحیح، تعریف نامکهای معنادار، توجه به ترجمه برچسبها و تعریف fallback مناسب. اشتباههای کوچک در این تابع اغلب به ناپدید شدن منو از پنل مدیریت یا رفتار غیرمنتظره در فرانتاند منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با Child Theme یا در Multisite — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.