TODO: To change the header's content go to Dr.Explain menu Options : Project Settings : HTML (CHM) Export : Setup HTML Template and Layout
×
Menu
Index

Tùy chỉnh menu

Bổ xung thêm menu item động.
function add_custom_nav($items, $args) {
    if ( $args->theme_location == 'main-nav' ){
         $items .= '<li>SEARCH</li>';
    }
    return $items;
}
add_filter('wp_nav_menu_items', 'add_custom_nav', 10, 2);
 
Practice:
 
Chỉ định gọi hook vào menu cụ thể, xác định tên menu/location bạn có thể tìm thấy tên menu đã đăng ký ở hàm register_nav_menu hoặc chuột phải để tìm vào phần tử ul hiển thị menu.
 
Tên hook theo từng menu có dạng: wp_nav_menu_{$menu->slug}_items. Ví dụ:
add_filter('wp_nav_menu_mainmenu_items', 'add_custom_nav', 10, 2);
Trong đó: mainmenu là tên menu, tên menu không được viết dấu cách.
 
Nếu bạn gõ tên menu như trên, menu tự động tạo bởi wordpress, như ở hình trên tên menu sẽ là 'main-menu-chinh'. Wordpress sẽ tự động thay dấu cách bằng ký tự -
 
Thêm ký tự ngăn giữa các menu items.
Cách 1: cách đơn giản nhất là sử dụng CSS
ul.menu li{
     border-right:1px solid gray;
}
 
Cách 2: truyền tham số vào hàm hiển thị menu wp_nav_menu()
wp_nav_menu(array(
     ...
     'walker'=>new themeslug_walker_nav_menu(),
     'ex_separator'=>'<li class="separator"></li>'     #set separator characters in argument.
     ...
));
 
Sử dụng class Walker_Nav_Menu
class themeslug_walker_nav_menu extends Walker_Nav_Menu {
    private $counter=0;
    // add classes to ul sub-menus
    function start_el(&$output, $item, $depth, $args) {
        $item->classes[]='nav'.(++$this->counter);
        if(//$this->counter &&
        isset($args->ex_separator))
        {
            $output .= $args->ex_separator;
        }
        parent::start_el($output, $item, $depth, $args);
    }
    function end_el(&$output, $item, $depth, $args){
        parent::end_el($output, $item, $depth, $args);
    }
}
 
Note: thẻ li đại diện cho các items của menu và chúng tạo bởi phương thức 'start_el'.
 
Xóa ul bao menu.
wp_nav_menu( array( 'items_wrap' => '%3$s' ) );
 
Thêm ký tự vào trước menu.
wp_nav_menu( array( 'theme_location' => 'primary', 'items_wrap' => '<ul><li id="item-id">Menu: </li>%3$s</ul>' ) );
 
Hiển thị menu home.
Để hiện menu home bạn thêm/thiết lập giá trị tham số show_home=true. Chèn đoạn code dưới đây vào file functions.php
function twentytwelve_page_menu_args( $args ) {
     if ( ! isset( $args['show_home'] ) )
          $args['show_home'] = true;
     return $args;
}
add_filter( 'wp_page_menu_args', 'twentytwelve_page_menu_args' );
 
Giờ bạn quay trở lại trang quản lý menu, tùy chọn Trang chủ sẽ hiển thị bạn chọn vào và ấn Thêm vào trình đơn.
 
Tùy chỉnh CSS.
- Thêm class cho nav menu item là tính năng sẵn có của wordpres.
Tuy nhiên, lựa chọn này wordpress mặc định cho ẩn. Thực hiện theo các bước để thêm class vào menu.
Vào Appearance->Menus, click vào tab Screen options.
Dưới mục Show advanced menu properties, check CSS classes. Ngay sau đó hiển thị hộp text tại đây nhập tên class thêm cho menu item đó.
 
 
- Cách khác chúng ta cũng có thể thêm css vào menu , bằng cách sử dụng filter 'nav_menu_css_class'.
/*
* customize menu css
*/
add_filter('nav_menu_css_class', 'special_nav_class', 10, 2);
function special_nav_class($classes, $item)
{
     if(in_array('current-menu-item',$item->classes)){    //current item
             $classes[]='nav_focus';
     }
         else $classes[]='nav_normal';
     //other of purpose
     preg_match('/[^\/]+$/', trim($item->url, '/'), $r); //get page
 
     if (is_page() && is_page($r[0]))
          $classes[]='active';
 
     return $classes;
}
Tham số:
 
Có một số class đặc biệt quy định bởi wordpress menu.
.current-menu-item: trang menu hiện tại người dùng đang xem.
.current-page-item: nội dung menu hiện tại là trang.
.menu-item-home: menu trang chủ.
 
Sửa nội dung menu:
Trước khi menu được hiển thị ra website bạn có thể sửa lại nội dung hiển thị menu với hook 'wp_nav_menu_items'. Ví dụ sau tự động thêm menu home vào trước menu.
//thêm menu item (ie: home,) (custom menu items)
add_filter('wp_nav_menu_items', 'add_home_link', 10, 2);
function add_home_link($items, $args)
{
     if (is_front_page()) $class='active';
 
     $homeMenuItem='<li class="' . $class . '">' . $args->before . '<a href="' . home_url('/') . '" title="HOME">'. $args->link_before . 'Home' . $args->link_after . '</a>' . $args->after . '</li>';
 
     $items=$homeMenuItem . $items;
     return $items;
}
 
Tùy biến thuộc tính liên kết menu.
Để thêm hay loại bỏ thuộc tính của thẻ a bạn sử dụng filter 'nav_menu_link_attributes'.
add_filter('nav_menu_link_attributes','custom_menu',10,3);
function custom_menu($atts, $item, $args){
    if($item->url=='/' && function_exists('qtrans_convertURL')){
        $atts['href'] = qtrans_convertURL($item->url);
    }
    return $atts;
}
 
Ví dụ trên, mình sửa đổi liên kết home nếu phát hiện plugin tạo đa ngôn ngữ qtranslate có cài đặt trong wordpress. Bạn cũng có thể sửa liên kết home với filter 'home_url' được tích hợp trong hàm home_url.
function qtrans_convertHomeURL($url, $what) {
    if($what=='/') return qtrans_convertURL($url);
    return $url;
}
 
add_filter('home_url', 'qtrans_convertHomeURL', 10, 2);
 
Sửa tham số hàm wp_nav_menu().
Mọi tham số bạn truyền vào hàm wp_nav_menu bạn có thể thay đổi thông qua hook 'wp_nav_menu_args'.
function modify_nav_menu_args( $args )
{
    if( 'primary' == $args['theme_location'] )
    {
        $args['depth'] = -1;
        $args['container_id'] = 'my_primary_menu';
    }
    if('menu1' == $args['menu']){    #maybe old wp version
        $args['walker'] = new custom_walker();
    }
    //for custom menu widget
    if(isset($args['menu']) && $args['menu']->name == 'menu-header')
   {
    ...
    }
    return $args;
}
 
add_filter( 'wp_nav_menu_args', 'modify_nav_menu_args' );
 
Giải thích thông tin đối tượng menu:
$args['menu']->slug;     #menu slug
$args['menu']->name;     #menu name
$args['menu']->term_id;     #menu id
 
Khi wp_nav_menu lấy giá trị mảng truyền vào, nó sẽ sử lý qua filter wp_nav_menu_args, do đó chúng ta có thể sửa lại mọi menu trước khi nó được hiển thị như đúng thiết lập tại vị trí gọi hàm hiển thị menu wp_nav_menu.
 
Tùy biến hiển thị menu item với 'walker_nav_menu_start_el'.
Chúng ta để ý có filter ‘walker_nav_menu_start_el‘ cho phép bạn tùy biến hiển thị menu bằng cách sửa hook này. Bạn có thể thêm vào functions.php như sau, ví dụ:
if (function_exists('qtrans_convertURL')) {
 
function qtrans_in_nav_el($output, $item, $depth, $args) {
 
     $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) . '"' : '';
 
     // Integration with qTranslate Plugin
 
     $attributes .=!empty($item->url) ? ' href="' . esc_attr( qtrans_convertURL($item->url) ) . '"' : '';
 
     $output = $args->before;
 
     $output .= '<a' . $attributes . '>';
 
     $output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
 
     $output .= '</a>';
 
     $output .= $args->after;
 
     return $output;
 
}
 
add_filter('walker_nav_menu_start_el', 'qtrans_in_nav_el', 10, 4);
 
}
 
Walker.
Menu Walker cho phép bạn chỉnh mọi thứ với nav menu, bạn có thể tham khảo chi tiết trong file wp-admin/nav-menus.php & wp-admin/menu.php
Ví dụ sau mình sẽ lấy tất cả menu items là con của 1 menu chỉ định sử dụng lớp Walker_Nav_Menu.
<?php  wp_nav_menu( array('menu' => 'header-menu', 'walker' => new JC_Walker_Nav_Menu(8)) ); ?>
 
class JC_Walker_Nav_Menu extends Walker_Nav_Menu {
 
    var $menu_id = 0;
    var $menu_items = array();
 
    function __construct($id = 0){
        $this->menu_id = $id;
        $this->menu_items[] = $id;
    }
 
    function start_el( &$output, $item, $depth, $args ) {
        if( !empty($this->menu_items) && !in_array($item->ID, $this->menu_items) && !in_array($item->menu_item_parent, $this->menu_items)){
            return false;
        }
 
        if(!in_array($item->ID, $this->menu_items)){
            $this->menu_items[] = $item->ID;
        }
       //do this
       $output .= apply_filters( 'walker_nav_menu_start_el', $output, $item, $depth, $args );
         //or: parent::start_el($output, $item, $depth, $args);
      
    }
 
    function end_el( &$output, $item, $depth = 0, $args = array() ) {
        if( !empty($this->menu_items) && !in_array($item->ID, $this->menu_items) && !in_array($item->menu_item_parent, $this->menu_items)){
                return false;
            }
    }
 
    function start_lvl(&$output, $depth=0, $args=array()) {
        if( 0 == $depth )
           return;   #Don't wrap the top level
 
        $indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
        $output .= $indent."\n<ul>\n";
        //parent::start_lvl($output, $depth, $args);   #don;t need
    }
    function end_lvl(&$output, $depth=0, $args=array()) {
        if( 0 == $depth )
           return;   #Don't wrap the top level
 
        $indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
        $output .= $indent."</ul>\n";
        //parent::end_lvl($output, $depth, $args);       #don't use
    }
 
}
 
Phương thức display_element, phương thức này giúp sử lý những item có chứa sub items bên dưới.
Ví dụ, chúng ta không cho hiển thị các menu ở top-level và URL hiện tại không thuộc về item đó.
// Only follow down one branch
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
 
    // Check if element as a 'current element' class
    $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );
    $current_class = array_intersect( $current_element_markers, $element->classes );
 
    // If element has a 'current' class, it is an ancestor of the current element
    $ancestor_of_current = !empty($current_class);
 
    // If this is a top-level link and not the current, or ancestor of the current menu item - stop here.
    if ( 0 == $depth && !$ancestor_of_current)
        return;
 
    parent::display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output );
}
 
Tạo một item đầy đủ bằng phương thức start_el.
    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        $indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
 
        $class_names = $value = '';
 
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;
 
        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
 
        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
 
        $output .= $indent . '<li' . $id . $value . $class_names .'>';
 
        // add span with number here
        if ( $depth == 0 ) { // remove if statement if depth check is not required
            $output .= sprintf( '<span>%02s.</span>', $this->number++ );
        }
 
        $atts = array();
        $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
        $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
        $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
        $atts['href']   = ! empty( $item->url )        ? $item->url        : '';
 
        $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
 
        $attributes = '';
        foreach ( $atts as $attr => $value ) {
            if ( ! empty( $value ) ) {
                $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }
 
        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $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=array()) {
        $indent = ( $depth ) ? str_repeat( "t", $depth ) : '';
        $output .= $indent."</li>n";
    }
 
 
Made with help of Dr.Explain

Unregistered version