WordPress Custom Menu: Tùy Biến Và Hiển Thị Menu Không Dùng Plugin

5/5 - (99 bình chọn)

Việc triển khai wordpress custom menu là kỹ năng nền tảng cho bất kỳ nhà phát triển theme nào. Menu mặc định thường bị giới hạn về vị trí và kiểu dáng. Bài viết này hướng dẫn chi tiết cách đăng ký và hiển thị các vị trí menu mới. Chúng ta sẽ làm việc trực tiếp với file Functions.phptheme’s template. Việc này giúp tối ưu hiệu suất trang web. Nó cũng mang lại sự linh hoạt cao hơn nhiều so với việc dựa vào các plugin. Bạn sẽ nắm vững hàm lõi register_nav_menu và hàm hiển thị wp_nav_menu.

Tại Sao Cần Tùy Biến Vị Trí Menu Trong WordPress?

Các theme WordPress thường chỉ cung cấp một hoặc hai vị trí menu mặc định. Chúng thường nằm ở header hoặc footer. Tuy nhiên, nhiều dự án đòi hỏi cấu trúc phức tạp hơn. Ví dụ, một menu cho sidebar, một menu cho thanh thông báo, hoặc menu cho Custom Post Types cụ thể.

Tùy biến cho phép bạn kiểm soát hoàn toàn vị trí hiển thị. Bạn có thể đặt menu tại bất cứ đâu trong cấu trúc theme. Điều này giúp cải thiện trải nghiệm người dùng. Nó cũng giúp quản lý nội dung tốt hơn.

Việc không sử dụng plugin cho các tác vụ cơ bản này là cần thiết. Nó giúp giảm thiểu rủi ro bảo mật và xung đột. Đồng thời, code lõi của theme sẽ gọn gàng và tải nhanh hơn. Đây là phương pháp chuyên nghiệp được cộng đồng WordPress khuyến nghị.

Đăng Ký Vị Trí Menu Tùy Chỉnh Mới (Register Custom Menu Location)

Bước đầu tiên để có wordpress custom menu là khai báo vị trí của nó. Khai báo này được thực hiện trong file functions.php của theme đang hoạt động. Bạn nên sử dụng trình soạn thảo văn bản chuyên nghiệp như Sublime Text để chỉnh sửa.

Sử dụng register_nav_menu()

Bạn cần mở file functions.php của theme. Sau đó, thêm đoạn mã sau vào cuối file. Đoạn mã này sử dụng hook add_action để gọi hàm đăng ký.

function my_custom_menu() { register_nav_menu('my-custom-menu',__( 'My Custom Menu' )); } add_action( 'init', 'my_custom_menu' );

Hàm add_action() móc chức năng của chúng ta vào hành động init. Hành động init chạy cùng với các hàm cốt lõi khác của WordPress. Điều này đảm bảo menu được đăng ký ngay khi WordPress khởi tạo.

Tham số đầu tiên 'my-custom-menu' là tên ID nội bộ (slug) của menu. Tên này được dùng để tham chiếu trong code. Tham số thứ hai, 'My Custom Menu', là phiên bản dễ đọc mà bạn sẽ thấy trong khu vực quản trị.

Đăng ký nhiều menu bằng register_nav_menus()

Nếu dự án yêu cầu nhiều vị trí menu tùy chỉnh, bạn có thể sử dụng hàm register_nav_menus() thay thế. Hàm này chấp nhận một mảng các vị trí menu. Mỗi vị trí được định nghĩa bằng một cặp ID và tên hiển thị.

Dưới đây là ví dụ đăng ký hai vị trí menu cùng lúc:

function my_custom_menu() { register_nav_menus( array( 'my-custom-menu' => _( 'My Custom Menu' ), 'my-custom-menu-2' =>_('My Second Custom Menu') ) ); } add_action( 'init', 'my_custom_menu' );

Sau khi thêm và lưu file functions.php, bạn cần kiểm tra lại kết quả. Truy cập khu vực quản trị WordPress. Điều hướng đến Appearance > Menus. Trong cài đặt Menu (Menu Settings), bạn sẽ thấy vị trí menu tùy chỉnh đã được liệt kê.

Lưu ý rằng việc đăng ký chỉ là bước khai báo vị trí. Tại thời điểm này, menu sẽ chưa hiển thị bất cứ thứ gì ở giao diện người dùng (frontend). Chúng ta cần thêm code hiển thị ở bước tiếp theo.

Xem thêm  bay Coffee Menu: Khám Phá Trải Nghiệm Ẩm Thực Độc Đáo Tại Bay Coffee

Hiển Thị Menu Tùy Chỉnh Ra Giao Diện Người Dùng

Để menu hiển thị, chúng ta cần chèn một hàm đặc biệt vào file template của theme. Vị trí chèn sẽ quyết định nơi menu xuất hiện trên trang.

Thêm code vào Theme Template (ví dụ: header.php)

Giả sử chúng ta muốn menu tùy chỉnh xuất hiện ngay dưới menu chính của theme. Trong ví dụ này, chúng ta sử dụng theme Twenty Twenty. Chúng ta sẽ chỉnh sửa file header.php. File này thường nằm trong thư mục gốc của theme.

Mở file header.php và tìm kiếm phần tử liên quan đến header theme. Trong theme Twenty Twenty, đoạn code sau thường nằm xung quanh dòng 33.

<div class="header-navigation-wrapper">

Ngay dưới phần tử này, chúng ta sẽ chèn hàm wp_nav_menu(). Hàm này chịu trách nhiệm hiển thị menu.

Giao diện file header.php của theme Twenty Twenty, nơi chèn code hiển thị wordpress custom menu

Đây là đoạn code cần chèn:

wp_nav_menu( array( 'theme_location' => 'my-custom-menu' ) ); 

Giá trị của theme_location phải trùng khớp tuyệt đối với ID nội bộ (my-custom-menu) đã đăng ký trong functions.php. Điều này tạo ra sự liên kết giữa vị trí khai báo và vị trí hiển thị. Hàm này sẽ tự động tìm menu đã được gán cho vị trí đó và render ra HTML.

Tạo Menu Test và Gán Vị Trí

Trước khi kiểm tra giao diện, chúng ta cần tạo một menu thực tế. Quay lại Appearance > Menus trong khu vực quản trị. Tạo một menu mới, ví dụ đặt tên là “Secondary Menu”.

Quan trọng là phải chọn vị trí hiển thị là “My Custom Menu” (tên dễ đọc) trong Menu Settings. Sau đó, nhấn “Create Menu”. Thêm vài mục menu như “Menu item 1”, “Menu item 2”, v.v., và lưu lại.

Giao diện tạo Menu phụ (Secondary Menu) trong quản trị WordPress và gán vị trí My Custom MenuGiao diện tạo Menu phụ (Secondary Menu) trong quản trị WordPress và gán vị trí My Custom Menu

Kiểm tra giao diện frontend, menu mới sẽ xuất hiện. Tuy nhiên, giao diện mặc định có thể không đẹp. WordPress sử dụng các thẻ <ul><li> cơ bản.

Kết quả hiển thị ban đầu của menu tùy chỉnh (wordpress custom menu) trước khi áp dụng CSS

Tùy chỉnh giao diện bằng CSS

Menu mới hiển thị cần được tạo kiểu để phù hợp với theme. Hàm wp_nav_menu() tự động tạo ra một cấu trúc HTML với các ID và class nhất định.

Cấu trúc HTML được tạo ra sẽ giống như sau (tùy thuộc vào tên menu bạn đặt):

<div class="menu-secondary-menu-container">
    <ul id="menu-secondary-menu" class="menu">
        <li id="menu-item-12" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-12">
            <a href="#">Menu item 1</a>
        </li>
        <!-- ... các menu item khác ... -->
    </ul>
</div>

Chúng ta sẽ sử dụng ID hoặc Class này để áp dụng CSS. Mở file style.css của theme (thường cùng vị trí với header.php). Thêm các quy tắc CSS để làm đẹp menu.

ul#menu-secondary-menu {
    text-align: right;
    padding: 10px 30px;
}
ul#menu-secondary-menu li {
    list-style: none;
    display: inline-block;
    padding: 1px;
}
ul#menu-secondary-menu li:hover {
    border: 1px solid #c00202;
    padding: 0;
    border-radius: 3px;
}
ul#menu-secondary-menu li a {
    text-decoration: none;
    padding: 5px;
    font-size: 14px;
}

Với việc áp dụng CSS này, menu sẽ trông gọn gàng và chuyên nghiệp hơn. Nó phù hợp hơn với phong cách thiết kế của website. Đây là bước quan trọng trong việc hoàn thiện wordpress custom menu.

Các Tham Số Tùy Biến Nâng Cao Cho Hàm wp_nav_menu()

Hàm wp_nav_menu() cực kỳ mạnh mẽ. Nó cung cấp hàng loạt tham số (arguments) để tùy chỉnh đầu ra HTML. Hiểu rõ các tham số này giúp bạn có thể kiểm soát chi tiết mọi khía cạnh của menu.

Tùy chỉnh ID và Class (menu_id, menu_class)

Hai tham số này cho phép bạn định nghĩa các thuộc tính CSS cho thẻ <ul> chứa menu.

Tham số menu_class cho phép bạn chỉ định lớp CSS riêng cho menu. Lớp này được thêm vào thẻ <ul>. Nó không thay thế các lớp mặc định.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'menu_class' => 'my-custom-menu-class' 
) ); 

Khi kiểm tra mã nguồn, bạn sẽ thấy lớp mới được thêm vào. Điều này giúp tăng tính đặc hiệu khi viết CSS.

Kiểm tra mã nguồn HTML sau khi áp dụng tham số menu_class cho wordpress custom menu

Tham số menu_id hoạt động khác. Nó sẽ thay thế ID mặc định của thẻ <ul>. Nếu không sử dụng tham số này, ID mặc định thường là slug của menu. ID này sẽ tự tăng nếu bạn gọi hàm nhiều lần.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'menu_id' => 'custom-unique-id' 
) );
// Kết quả HTML: <ul id="custom-unique-id" class="menu">...</ul>

Kiểm soát phần tử bao quanh (container, container_class)

Theo mặc định, WordPress bao quanh thẻ <ul> bằng thẻ <div>. Bạn có thể thay đổi loại phần tử bao quanh này bằng tham số container.

Nếu muốn sử dụng thẻ <nav> thay cho <div>, bạn thiết lập như sau:

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'container' => 'nav', 
) ); 

Nếu bạn không muốn có phần tử bao quanh nào, chỉ cần đặt containerfalse hoặc một chuỗi rỗng.

Xem thêm  Trà Sữa Zen Menu: Khám Phá Hương Vị Tinh Hoa Tại Biên Hòa

Tham số container_class cho phép bạn áp dụng lớp CSS cho phần tử bao quanh. Điều này hữu ích để tạo kiểu cho vùng chứa menu.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'container_class' => 'my-custom-menu-wrapper', 
) ); 

Kết quả sẽ tạo ra thẻ chứa có lớp tùy chỉnh.

Mã nguồn HTML hiển thị phần tử bao quanh container_class của vị trí menu mới trong WordPressMã nguồn HTML hiển thị phần tử bao quanh container_class của vị trí menu mới trong WordPress

Thêm nội dung trước và sau liên kết (before, after, link_before, link_after)

Các tham số này cho phép bạn chèn nội dung vào cấu trúc menu ở cấp độ item và link.

  • before: Nội dung được chèn ngay trước thẻ <li class="menu-item">.
  • after: Nội dung được chèn ngay sau thẻ </li>.
  • link_before: Nội dung được chèn ngay trước thẻ <a>.
  • link_after: Nội dung được chèn ngay sau thẻ </a>.

Ví dụ, để bọc văn bản liên kết trong thẻ <span>, chúng ta sử dụng link_beforelink_after.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'link_before' => '<span>', 
    'link_after' => '</span>', 
) );

Bạn có thể chèn các biểu tượng (icons) bằng cách sử dụng các tham số này. Nếu bạn đã cài đặt plugin Font Awesome, bạn có thể thêm icon bằng cách chèn mã HTML của icon đó vào link_before.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'link_before' => '<i class="fa fa-chevron-right"></i> ', // Ví dụ sử dụng Font Awesome
) ); 

Bạn có thể tham khảo danh sách icon trên trang chính thức của plugin Font Awesome.

Tối ưu hóa hiển thị (depth, fallback_cb, items_wrap)

Đây là các tham số quan trọng để kiểm soát cấu trúc và sự ổn định. Việc tối ưu hóa các tham số này là dấu hiệu của chuyên môn cao.

Tham số depth kiểm soát số lượng cấp độ menu được hiển thị. Giá trị mặc định là 0 (hiển thị tất cả). Nếu bạn chỉ muốn hiển thị menu cấp một, đặt depth là 1. Điều này hữu ích khi bạn có nhiều menu phụ, phức tạp.

Tham số fallback_cb định nghĩa hàm dự phòng nếu không tìm thấy menu. Mặc định, WordPress sẽ hiển thị danh sách các trang.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'fallback_cb' => false // Không hiển thị gì nếu menu không được gán
) );

Hoặc bạn có thể tự viết một hàm dự phòng tùy chỉnh. Hàm này sẽ thông báo cho người dùng biết cần tạo menu.

Tham số items_wrap cho phép bạn định nghĩa cấu trúc HTML bao quanh các item menu. Giá trị mặc định là <ul id="%1$s" class="%2$s">%3$s</ul>.

  • %1$s: Dành cho ID của menu.
  • %2$s: Dành cho Class của menu.
  • %3$s: Dành cho tất cả các item menu (<li>).

Nếu muốn bọc menu bằng một thẻ <section> đặc biệt, bạn có thể thay đổi items_wrap.

wp_nav_menu( array( 
    'theme_location' => 'my-custom-menu', 
    'items_wrap' => '<section class="menu-items-list">%3$s</section>'
) );

Sử dụng items_wrap cho phép tùy biến sâu hơn nữa. Nó tách biệt cấu trúc hiển thị khỏi logic code chính. Bạn có thể dễ dàng kiểm tra các bài viết khác trên hanoidep.vn để xem ứng dụng thực tế của việc tối ưu hóa hiệu suất web.

Tùy Biến Cấu Trúc Menu Với WordPress Walker Class

Đối với các nhà phát triển chuyên nghiệp, việc tùy chỉnh HTML đầu ra sâu hơn là cần thiết. Đặc biệt khi bạn cần menu tuân thủ các chuẩn CSS framework như Bootstrap. WordPress cung cấp Walker Class để kiểm soát chi tiết từng thẻ HTML của menu.

Hiểu về Walker Class và vai trò của nó

Walker Class là một lớp trừu tượng (abstract class). Nó giúp bạn duyệt qua cấu trúc dữ liệu phân cấp. Trong trường hợp menu, nó duyệt qua các mục menu (cấp cha, cấp con).

Xem thêm  Electronic Menu Software: Giải Pháp Tối Ưu Hóa Trải Nghiệm Khách Hàng

Mặc định, WordPress sử dụng Walker_Nav_Menu. Lớp này nằm trong file wp-includes/class-walker-nav-menu.php. Để thay đổi HTML đầu ra, chúng ta cần tạo một lớp kế thừa và ghi đè (override) các phương thức của nó.

Các phương thức quan trọng bao gồm:

  • start_lvl()end_lvl(): Định nghĩa thẻ bao quanh các menu cấp con (<ul> hoặc <div>).
  • start_el()end_el(): Định nghĩa thẻ bao quanh từng mục menu (<li><a>).

Để chứng minh, chúng ta sẽ thêm một mục menu phụ (Sub item) trong khu vực quản trị.

Minh họa cấu trúc menu đa cấp với Sub Item để thử nghiệm Walker ClassMinh họa cấu trúc menu đa cấp với Sub Item để thử nghiệm Walker Class

Thực hiện Custom Walker Class

Để tạo Custom Walker Class, chúng ta thêm đoạn mã sau vào file functions.php. Chúng ta cần kiểm tra sự tồn tại của lớp trước khi khai báo. Điều này ngăn chặn lỗi fatal error.

if ( !class_exists('My_Nav_Menu_Walker') ) { 
    class My_Nav_Menu_Walker extends Walker { 
        var $tree_type = array( 'post_type', 'taxonomy', 'custom' ); 
        var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' ); 

        function start_lvl(&$output, $depth, $args = null) { 
            $indent = str_repeat("t", $depth); 
            $output .= "n$indent"; 
            $output .= "n"; 
            $output .= "<div>n"; // Thay thế <ul> bằng <div>
        } 

        function end_lvl(&$output, $depth, $args = null) { 
            $indent = str_repeat("t", $depth); 
            $output .= "$indent</div>n"; // Đóng </div>
        } 

        function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) { 
            $value = ''; 
            $classes = empty( $item->classes ) ? array() : (array) $item->classes; 
            $classes = in_array( 'current-menu-item', $classes ) ? array( 'current-menu-item' ) : array(); 
            $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) ); 
            $class_names = strlen( trim( $class_names ) ) > 0 ? ' class="' . esc_attr( $class_names ) . '"' : ''; 

            $id = apply_filters( 'nav_menu_item_id', '', $item, $args ); 
            $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : ''; 

            $attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : ''; 
            $attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : ''; 
            $attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : ''; 
            $attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : ''; 

            $item_output = $args->before; 
            $item_output .= '<a ' . $class_names . ' ' . $id . ' ' . $attributes . '>'; 
            $item_output .= '<div>'; // Bọc nội dung liên kết trong <div>
            $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after; 
            $item_output .= '</div>'; 
            $item_output .= "</a>n"; 
            $item_output .= $args->after; 

            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); 
        } 
    } 
}

Trong đoạn code trên, chúng ta đã thay đổi cấu trúc của submenu. Cấp submenu đã được bọc bằng thẻ <div> thay vì <ul>. Ngoài ra, chúng ta bọc tiêu đề liên kết bằng một thẻ <div> bổ sung.

So sánh kết quả

Cuối cùng, chúng ta áp dụng Walker Class tùy chỉnh này khi gọi hàm wp_nav_menu(). Trong file header.php, chúng ta sẽ tạm thời hiển thị cả hai phiên bản menu để so sánh.

Menu mặc định (sử dụng Walker_Nav_Menu):

wp_nav_menu();

Menu sử dụng Custom Walker:

wp_nav_menu( array( 'walker' => new My_Nav_Menu_Walker() ) ); 

Bạn sẽ thấy rõ sự khác biệt trong cấu trúc HTML đầu ra. Menu sử dụng Walker tùy chỉnh sẽ có cấu trúc mới.

So sánh kết quả hiển thị giữa menu mặc định và menu sử dụng Custom Walker ClassSo sánh kết quả hiển thị giữa menu mặc định và menu sử dụng Custom Walker Class

Bằng cách so sánh mã nguồn và kết quả hiển thị, bạn có thể hiểu rõ tác động của Custom Walker. Nó mang lại khả năng tùy biến HTML không giới hạn.

Nắm vững Walker Class là chìa khóa để xây dựng theme WordPress chất lượng cao. Nó đảm bảo mã nguồn HTML sạch và tuân thủ các tiêu chuẩn. Nếu bạn quan tâm đến việc nâng cao kỹ năng phát triển, hãy nghiên cứu lập trình hướng đối tượng (OOP) trong WordPress. Các kỹ thuật này sẽ cải thiện khả năng tái sử dụng và tính bảo mật của mã nguồn.


Kiểm soát hoàn toàn wordpress custom menu là điều cần thiết. Nó giúp nhà phát triển theme cung cấp trải nghiệm tối ưu. Việc đăng ký vị trí, hiển thị bằng wp_nav_menu(), và tùy chỉnh nâng cao bằng Walker Class đều nằm trong tầm tay bạn. Bạn đã học được cách thêm các vị trí menu linh hoạt mà không cần dựa vào plugin. Điều này không chỉ tăng tốc độ mà còn giúp mã nguồn theme gọn gàng hơn. Kỹ năng này mở ra nhiều khả năng thiết kế mới khi xây dựng website. Việc áp dụng các tham số tối ưu và hiểu sâu về cấu trúc code sẽ đảm bảo chất lượng kỹ thuật cao nhất cho dự án của bạn.

Ngày Cập Nhật: Tháng 11 26, 2025 by Ngô Hồng Thái

Avatar photo
Ngô Hồng Thái

Ngô Hồng Thái từng có hơn 20 năm kinh nghiệm trong ngành báo chí truyền thống. Chính nền tảng này đã rèn luyện cho anh một con mắt quan sát tinh tế, khả năng phát hiện những câu chuyện bình dị nhưng đầy ý nghĩa trong cuộc sống. Anh không chỉ là một nhiếp ảnh gia bấm máy mà còn là một nhà báo kể chuyện bằng ngôn ngữ.

Bài viết: 27941

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *