Tự động loại trừ các mục menu khỏi wp_nav_menu


17

Tôi đã cố gắng tìm kiếm thông tin về cách loại trừ / loại bỏ các mục menu điều hướng khỏi các menu tùy chỉnh và chủ đề duy nhất tôi tìm thấy không có bất kỳ câu trả lời nào hữu ích cho tôi.

1. Bối cảnh:

Tôi kết hợp một menu Dock bằng các menu tùy chỉnh WP (wp_nav_menu) và jqDock trên trang web của tôi. Vì jqDock cần hình ảnh liên kết hoặc liên kết hình ảnh để thực hiện phép thuật của mình, tôi sử dụng một trình đi bộ tùy chỉnh để đầu ra HTML của menu điều hướng trông giống như thế này:

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>

Mã cho walker tùy chỉnh của tôi là:

class custom_nav_walker extends Walker_Nav_Menu 
{
    var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul>\n";
    }

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $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="' . esc_attr( $class_names ) . '"';

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

        //$output .= $indent . '<li' . $id . $value . $class_names .'>';

        $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        ) .'"' : '';

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : '';

        if ( strpos($description, ';') !== false ) {
        $description_array = explode (';', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$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) {
        $output .= "";
    }

}

Tập lệnh jqDock sau đó bắt ID menu ('menu-first') và thay thế đầu ra wp_nav_menu bằng menu Dock. Đầu ra HTML của menu Dock thay đổi dựa trên các tùy chọn được chỉ định khi tải jqDock.

2. Câu hỏi:

Tôi muốn không hiển thị (nghĩa là loại trừ) một số mục menu nhất định theo nơi người dùng đang ở trên trang web. Ví dụ: tôi muốn chỉ hiển thị mục Trang chủ khi người dùng không ở trong Trang chủ và mục đăng bài Ngẫu nhiên chỉ khi có.

3. Các giải pháp bị loại bỏ:

a. Menu Mulipl: Đăng ký và tạo nhiều menu và sau đó gọi chúng theo điều kiện có thể hoạt động; tuy nhiên, tôi không nghĩ rằng đây là một lý tưởng hay một giải pháp sạch vì nhiều lý do. Ngoài ra, nhiều menu không dễ bảo trì hoặc cập nhật.

b. Tìm kiếm và thay thế Regex: Điều này có thể buộc tôi thay đổi tham số kim mỗi khi tôi thay đổi tùy chọn jqDock vì đầu ra HTML bị sửa đổi.

c. Thuộc tính 'display' CSS: Ẩn các mục thông qua thuộc tính hiển thị CSS hoạt động, nhưng vì nó phải được áp dụng cho đầu ra menu jqDock, nó ảnh hưởng đến kết xuất trực quan của menu.

4. Giải pháp thất bại:

a. Bộ lọc cho wp_nav_menu_items : Tôi đã thử bắt biến '$ items' (chuỗi) và gán cho nó các giá trị khác nhau thông qua các thẻ có điều kiện với mã sau:

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode('<a', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode('<a', $items_array_home);
    $items_nothome = implode('<a', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');

Điều này chỉ hoạt động một phần, vì các mục menu thay đổi, nhưng các thẻ điều kiện bị bỏ qua. Tôi đoán điều này có ý nghĩa vì thời điểm mà bộ lọc được áp dụng.

b. Chức năng menu điều hướng tùy chỉnh : Tôi đã thử tạo chức năng menu điều hướng tùy chỉnh của riêng mình để có thể thêm đối số loại trừ vào mảng $ mặc định và sử dụng mã được sửa đổi một chút này wp_list_pagesđể điền vào đối số bổ sung:

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

Có ý kiến ​​gì không?


Bạn có thể chỉ cho chúng tôi lớp trẻ em đi bộ tùy chỉnh của bạn?
soulseekah

Xin chào Souleseekah, tôi chỉ cần thêm nó vào bài viết gốc của mình. Cảm ơn!
Marventus

Tôi đã nghĩ đến việc chuyển một excludeđối số quá, nhưng, trái với wp_list_pagesvà nhiều hàm WP khác, wp_nav_menukhông bao gồm một đối số. Vì vậy, ngay cả khi tôi chỉ định một cái khi gọi menu hoặc trong khung tập đi, nó sẽ không được chọn bên trong wp_nav_menu, phải không?
Marventus

Xin lỗi, tôi đã không nghĩ thẳng khi tôi viết nó, xóa ngay lập tức.
soulseekah

Đừng lo lắng về điều đó!
Marventus

Câu trả lời:


26

Phương pháp 1

Bạn có thể thêm một hàm tạo vào Walker tùy chỉnh của mình để lưu trữ một số đối số loại trừ bổ sung, như:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

Hoặc thả hàm tạo và đặt thuộc tính của nó $excludetrước khi chuyển nó vào như một khung tập đi để wp_nav_menu()thích:

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

Tùy thuộc vào những gì bạn loại trừ bởi, cung cấp biểu mẫu chính xác để loại trừ.

Phương pháp 2

Đây là cách bạn sẽ thực hiện việc này bằng cách nối vào wp_get_nav_menu_itemsbộ lọc.

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

Lưu ý: object_idlà đối tượng mà menu trỏ đến, trong khi IDlà ID menu, chúng khác nhau.

Hãy để tôi biết suy nghĩ của bạn.


Cảm ơn! Điều đó có thể làm việc. Tôi sẽ thử và cho bạn biết.
Marventus

Tôi đã thử phương pháp tiếp cận và, bất kể tôi thử gì, tôi vẫn nhận được lỗi "Sai kiểu dữ liệu cho đối số thứ hai" cho in_arrayhàm. Tôi có làm điều gì sai?
Marventus

Tài $excludesản phải là một mảng. Vì vậy, hãy chắc chắn rằng bạn đang truyền một mảng vào hàm tạo hoặc xem mã được cập nhật trong câu trả lời của tôi. Cụ thể là typecast cho $this->exclude, chỉ trong trường hợp một mảng không được thông qua.
soulseekah

Xin lỗi về điều đó: Tôi đã có một lỗi đánh máy trong chức năng của mình. Tôi cũng đã thử $exclude = array ('4', '7');và sử dụng các con sên, nhưng nó không có bất kỳ ảnh hưởng nào đến đầu ra của walker. Tôi sẽ thử cách tiếp cận thứ hai và cho bạn biết.
Marventus

Không, điều đó cũng không làm việc. Tôi nghĩ rằng tôi đã chết não khi cố gắng tìm ra điều này, vì vậy điều đó có thể ảnh hưởng đến ... "hiệu suất" của tôi, :-)
Marventus

0

không giúp đỡ à

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

làm ví dụ

< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>

Xin chào Saq, tôi đã quên đề cập rằng một trong những giải pháp không hoạt động là tạo một hàm nav_menu tùy chỉnh và thêm mã đó làm đối số bổ sung cho mặc định của hàm. Đáng buồn thay, nó đã không làm việc. Tôi đã không cố gắng đưa nó vào xe tập đi, nhưng tôi không nghĩ rằng nó sẽ hoạt động vì lý do tương tự như tôi đã đề cập ở trên, chủ yếu là wp_nav_menukhông có đối số "loại trừ", nhưng tôi có thể sai.
Marventus

Tôi đã cập nhật bài viết gốc của mình để bao gồm điều này cho rõ ràng.
Marventus

Điều gì xảy ra nếu bạn không sử dụng máy đi bộ tùy chỉnh, thay vào đó bạn sử dụng nav_menu thông thường và trích xuất các mục với wp_get_nav_menu_items () với hình ảnh tùy chỉnh của bạn
saq

Nói chung đó sẽ là một cách giải quyết tốt, nhưng trong trường hợp cụ thể này, wp_get_nav_menu_itemssẽ không truy xuất hình ảnh vì các thẻ img không được lưu trong menu tùy chỉnh thực tế (chỉ tên tệp của chúng nằm trong trường mô tả, ví dụ: "image1.png" ). Trình đi bộ tùy chỉnh là thứ cho phép tôi chèn các thẻ img trong đầu ra menu.
Marventus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.