چرا منوی HTML دستساز در وردپرس همیشه ناقص است؟ راهنمای wp_nav_menu
تابع wp_nav_menu برای نمایش منوهای مدیریتشده در وردپرس؛ بررسی پارامترها، theme_location، container، fallback و اشتباهات رایج در قالبنویسی.
چرا منوی دستساز در وردپرس ناکافی است؟
در قالبهای اولیه، منوها بهصورت ثابت در فایل هدر نوشته میشدند. این رویکرد چند مشکل جدی دارد: اول اینکه هر تغییر در منو نیازمند ویرایش کد است. دوم اینکه کاربر نمیتواند آیتمی اضافه یا حذف کند. سوم اینکه مدیریت منوهای چندسطحی بهصورت دستی بسیار پرخطاست. وردپرس با معرفی توابعregister_nav_menus() و wp_nav_menu() این مشکل را حل کرد. مکانهای منو در قالب ثبت میشوند و آیتمها از پنل مدیریت قابل ویرایش هستند. تابع wp_nav_menu() وظیفه نمایش نهایی را بر عهده دارد و در سراسر قالبهای حرفهای استفاده میشود.
تابع wp_nav_menu چیست؟
تابعwp_nav_menu() یک تابع هسته وردپرس است که در فایل wp-includes/nav-menu-template.php تعریف شده است. این تابع یک منوی مشخص را با پارامترهای دادهشده در قالب HTML نمایش میدهد.
منوها معمولاً با register_nav_menus() ثبت میشوند و سپس کاربر در پیشخوان، آیتمها را به هر مکان اختصاص میدهد. تابع wp_nav_menu() با پارامتر theme_location منوی مربوطه را پیدا و نمایش میدهد.
نکته مهم این است که این تابع خروجی HTML ساختاریافته با کلاسهای استاندارد تولید میکند که بهراحتی با CSS استایل میگیرد.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function wp_nav_menu( $args = array() ) {
// ...
}
پارامتر ورودی یک آرایه انجمنی است که میتواند شامل پارامترهای زیر باشد:
- theme_location: نامک مکان منو
- menu: شناسه یا نام منو
- container: تگ نگهدارنده منو (مثلاً nav یا div)
- container_class: کلاس تگ نگهدارنده
- container_id: شناسه تگ نگهدارنده
- menu_class: کلاس تگ ul
- menu_id: شناسه تگ ul
- depth: عمق مجاز منو
- fallback_cb: تابع جایگزین در صورت نبود منو
- walker: شیء Walker برای سفارشیسازی خروجی
- items_wrap: قالب نگهدارنده آیتمها
- link_before و link_after: متن پیش و پس از هر لینک
سازوکار داخلی تابع
تابعwp_nav_menu() ابتدا با پارامترهای دادهشده، منوی مناسب را پیدا میکند. اگر theme_location داده شده باشد، وردپرس به دنبال منویی میگردد که به آن مکان اختصاص یافته است.
اگر منویی پیدا نشد و fallback_cb روی false باشد، هیچ خروجی تولید نمیشود. اگر fallback_cb یک تابع باشد، آن تابع فراخوانی میشود. مقدار پیشفرض fallback_cb، تابع wp_page_menu است که فهرست صفحات را نمایش میدهد.
نکته مهم این است که این تابع نتایج را کش میکند. اگر مکرراً روی یک صفحه فراخوانی شود، هزینه اضافی ندارد.
پارامترهای کلیدی
پارامترtheme_location پرکاربردترین پارامتر این تابع است. این پارامتر نامک مکانی است که در register_nav_menus ثبت شده است.
پارامتر container تعیین میکند که منو در چه تگ HTML قرار گیرد. مقدار پیشفرض div است، اما برای سازگاری با HTML5 بهتر است nav انتخاب شود.
پارامتر depth عمق منو را کنترل میکند. مقدار ۰ به معنای بدون محدودیت است. برای منوهای یکسطحی، مقدار ۱ مناسب است.
پارامتر fallback_cb رفتار پیشفرض در صورت نبود منو را تعیین میکند. برای جلوگیری از نمایش فهرست صفحات (رفتار پیشفرض) وردپرس، مقدار false بدهید.
پارامتر items_wrap قالب نگهدارنده آیتمهای منو را تعیین میکند. مقدار پیشفرض:
'<ul id="%1$s" class="%2$s">%3$s</ul>'
میتوانید این مقدار را برای سازگاری با فریمورکهای CSS تغییر دهید.
کاربردهای عملی در هدر و فوتر
نمونه ساده در هدر:<header class="site-header">
<nav class="primary-navigation" aria-label="منوی اصلی">
<?php
wp_nav_menu( array(
'theme_location' => 'primary',
'container' => false,
'menu_class' => 'primary-menu',
'depth' => 3,
'fallback_cb' => false,
) );
?>
</nav>
</header>
نکته مهم: در این الگو، container روی false تنظیم شده است تا وردپرس تگ نگهدارنده اضافی تولید نکند. این کار زمانیکه خودتان تگ nav را دور منو گذاشتهاید، تمیزتر است.
نمونه منوی فوتر:
<?php
wp_nav_menu( array(
'theme_location' => 'footer',
'container' => false,
'menu_class' => 'footer-menu',
'depth' => 1,
'fallback_cb' => false,
) );
?>
نمونه منو با پیام جایگزین:
function mytheme_menu_fallback() {
echo '<ul class="primary-menu"><li><a href="' .
esc_url( home_url( '/' ) ) .
'">صفحه اصلی</a></li></ul>';
}
wp_nav_menu( array(
'theme_location' => 'primary',
'fallback_cb' => 'mytheme_menu_fallback',
) );
نکته مهم: در تابع جایگزین، از esc_url برای URL و esc_html برای متن استفاده شده است. راهنمای این تابع در صفحه esc_html آمده است.
سفارشیسازی خروجی با Walker
کلاسWalker_Nav_Menu امکان بازنویسی خروجی HTML منو را فراهم میکند. با ساخت یک کلاس سفارشی، میتوان ساختار مگا منو یا منو با سطوح پیچیده را پیاده کرد.
الگوی ساده:
class Mytheme_Mega_Walker extends Walker_Nav_Menu {
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
// پیادهسازی دلخواه
}
}
سپس در فراخوانی wp_nav_menu:
wp_nav_menu( array(
'theme_location' => 'primary',
'walker' => new Mytheme_Mega_Walker(),
) );
نکته مهم: ساخت Walker سفارشی برای منوهای معمولی زائد است. تنها در صورت نیاز به ساختار HTML پیچیده (مانند مگا منو یا ستونبندی) از این الگو استفاده کنید.
ناوبری موبایل و تست
طراحی منوی موبایل یکی از چالشهای اصلی قالبنویسی است. یک رویکرد حرفهای، استفاده از همان منوی اصلی با CSS متفاوت برای موبایل است. رویکرد دیگر، ثبت یک مکان منوی جداگانه برای موبایل است. رویکرد اول (منوی واحد با CSS موبایل) سادهتر است و نیاز به مدیریت دو منو ندارد. برای این کار، از CSS Media Query و دکمه همبرگر استفاده کنید. رویکرد دوم (دو منوی جداگانه) امکان مدیریت مستقل را فراهم میکند اما برای مدیر سایت پیچیدهتر است. در هر دو رویکرد، تست موبایل الزامی است. باید منو را در اندازههای مختلف صفحه تست کنید و مطمئن شوید که: - دکمه همبرگر بهدرستی کار میکند - آیتمهای زیرمنو در موبایل قابل دسترسی هستند - منو با کشیدن انگشت قابل بستن است - دسترسیپذیری با صفحهخوان حفظ شده استنکات امنیتی و اشتباهات رایج
اشتباه اول، نبودfallback_cb است. اگر fallback_cb تعریف نشود، وردپرس فهرست صفحات را نمایش میدهد که معمولاً مطلوب نیست.
اشتباه دوم، نبود شرط برای بررسی وجود منو است. در افزونهها، بهتر است ابتدا وجود منو را بررسی کنید:
if ( has_nav_menu( 'primary' ) ) {
wp_nav_menu( array( 'theme_location' => 'primary' ) );
}
اشتباه سوم، نبود استایل مناسب است. خروجی HTML وردپرس ساختار استانداردی دارد، اما برای طراحی زیبا باید CSS اختصاصی نوشت.
اشتباه چهارم، نبود تست موبایل است. منوی دسکتاپ ممکن است در موبایل بهدرستی کار نکند.
اشتباه پنجم، نبود escape در fallback است. اگر در تابع جایگزین، URL یا متن چاپ میکنید، از esc_url و esc_html استفاده کنید.
اشتباه ششم، نبود توجه به Accessibility است. استفاده از aria-label روی تگ nav و مدیریت فوکوس کیبورد در منوی موبایل ضروری است.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعwp_nav_menu() یک نقطه معماری در لایه نمایش است که بر چند جنبه از سیستم اثر میگذارد. لایه اول لایه اتصال منو به مکان است. این تابع بر پایه پارامتر theme_location منو را از پایگاه داده بازیابی میکند و با استفاده از ساختار درختی، خروجی HTML تولید میکند.
لایه دوم لایه فیلترپذیری است. فیلتر wp_nav_menu_args امکان تغییر پارامترها را فراهم میکند. فیلتر wp_nav_menu_items امکان افزودن یا تغییر آیتمها را میدهد. فیلتر wp_nav_menu_objects امکان دسترسی به اشیاء منو را فراهم میکند.
لایه سوم لایه امنیت است. کلاسها، URLها و متنها در HTML نهایی با توابع escape پاکسازی میشوند. با این حال، در تابعهای جایگزین (fallback) باید خودتان escape را رعایت کنید.
لایه چهارم لایه کشینگ است. خروجی این تابع بهطور پیشفرض کش نمیشود، اما قالبهای بهینهسازی و افزونههای Cache ممکن است آن را کش کنند. اگر منو بر اساس وضعیت کاربر تغییر میکند، باید استراتژی کش مناسب انتخاب شود.
لایه پنجم لایه Multisite است. در شبکههای Multisite، هر سایت میتواند منوهای متفاوتی داشته باشد. تابع wp_nav_menu در هر سایت بر پایه دادههای همان سایت کار میکند.
لایه ششم لایه Performance است. منوهای بزرگ یا منوهایی با سطوح عمیق، حجم HTML را افزایش میدهند. در پروژههای بزرگ، بهتر است تعداد آیتمهای منو و عمق آنها کنترل شود.
لایه هفتم لایه Accessibility است. ساختار منو باید با استانداردهای WCAG سازگار باشد. استفاده از تگ nav، برچسب مناسب (aria-label) و مدیریت فوکوس کیبورد از اصول پایه است.
لایه هشتم لایه تست است. تستهای End-to-End باید مطمئن شوند که منو در همه اندازههای صفحه و با همه مرورگرها بهدرستی کار میکند. مفاهیم پایهای منو در Menu در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای register_nav_menus، راهنمای add_theme_support، راهنمای get_header، راهنمای get_footer، راهنمای body_class و راهنمای get_template_part مراجعه کنید.
پرسشهای پرتکرار
تفاوتwp_nav_menu و wp_page_menu چیست؟ اولی منوهای مدیریتشده و دومی فهرست صفحات را نمایش میدهد. تابع دوم بهعنوان fallback پیشفرض استفاده میشود.
چطور از نمایش منو در صفحهای خاص جلوگیری کنیم؟ با شرط has_nav_menu پیش از فراخوانی.
چطور کلاس سفارشی به منو اضافه کنیم؟ با پارامتر menu_class یا container_class.
آیا منو در موبایل خودکار ریسپانسیو میشود؟ خیر، برای موبایل نیاز به CSS و JavaScript اختصاصی دارید.
چطور آیتم خاصی به منو اضافه کنیم؟ با فیلتر wp_nav_menu_items.
نتیجه و مسیر ادامه
تابعwp_nav_menu() ابزار اصلی وردپرس برای نمایش منوهای مدیریتشده در قالب است. استفاده درست از آن یعنی ترکیب با register_nav_menus، تعریف fallback_cb مناسب، توجه به ساختار HTML5 و طراحی موبایل، رعایت دسترسیپذیری و تست در محیطهای مختلف. اشتباههای کوچک در این تابع اغلب به تجربه ضعیف کاربر یا ناوبری ناقص منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در ترکیب با Walker سفارشی یا در طراحی موبایل — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.