Показать описание пункта меню с разрывами строк


У меня проблема с моей темой...

Я использую Agama, и я поставил галочку "описание" в настройках меню, но оно не будет отображаться на интерфейсе, так как тема этого не позволяет.

Но потом я нашел эту функцию:

function prefix_nav_description( $item_output, $item, $depth, $args ) {
if ( !empty( $item->description ) ) {
    $item_output = str_replace( $args->link_after . '</a>', '<span class="menu-item-description">' . $item->description . '</span>' . $args->link_after . '</a>', $item_output );
}
return $item_output;
}
add_filter( 'walker_nav_menu_start_el', 'prefix_nav_description', 10, 4 );

Это помогло мне получить описание, которое будет показано. Но я не могу делать разрывы строк в своем описании. Каждый раз, когда я просто делаю разрыв строки или вставляю
и сохраняю изменения, он снова удаляет изменения.

Так может кто-нибудь, помогите мне с функцией, которая позволяет отображать описание, а также позволяет мне добавлять
в описание.

Спасибо: D

Author: Krzysiek Dróżdż, 2018-03-14

1 answers

Хорошо, мне потребовалось некоторое время, чтобы отладить это поведение, но... Сейчас мне все ясно... Я не уверен, что это полностью преднамеренно...

Почему это так?

Итак... Разрывы строк хранятся в БД правильно. Затем в wp_setup_nav_menu_item поле описания заполняется на основе столбца post_content данного пункта меню.

В строке 845 (https://core.trac.wordpress.org/browser/tags/4.9/src/wp-includes/nav-menu.php#L845 ) он сокращен и отфильтрованный:

if ( ! isset( $menu_item->description ) ) {
    /**
     * Filters a navigation menu item's description.
     *
     * @since 3.0.0
     *
     * @param string $description The menu item description.
    */
    $menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) );
}

И функция wp_trim_words обрезает текст до определенного количества слов, но не сохраняет разрывы строк - поэтому любой разрыв строки заменяется пробелом.

Так что же мы можем с этим поделать?

В wp_trim_words нет фильтров, которые позволили бы нам изменить его поведение. Также нет фильтров, которые позволят нам пропустить вызов wp_trim_words, но...

Вы можете заменить \n некоторым заполнителем, а затем использовать фильтр nav_menu_description, чтобы заменить его обратно. Там даже нет нужно, чтобы пользователи сами вставляли этот заполнитель - мы можем заменить их заполнителем с save_post фильтром:

function replace_nl_placeholder_nav_menu_description( $description ) {
    return str_replace('%NL% ', "\n", $description);
}
add_filter('nav_menu_description', 'replace_nl_placeholder_nav_menu_description');

function replace_nl_with_placeholder_nav_menu_description( $post_id ) {
    if ( 'nav_menu_item' !== get_post_type($post_id) ) return;

    remove_action( 'save_post', 'replace_nl_with_placeholder_nav_menu_description' );

    wp_update_post( array(
        'ID' => $post_id,
        'post_content' => str_replace("\n", '%NL% ', get_post_field('post_content', $post_id, 'raw'))
    ) );

    add_action( 'save_post', 'replace_nl_with_placeholder_nav_menu_description' );
}
add_action( 'save_post', 'replace_nl_with_placeholder_nav_menu_description' );

И это все. Вам нужно только помнить, чтобы правильно отображать такие разрывы строк в вашей теме (nl2br и так далее).

 3
Author: Krzysiek Dróżdż, 2018-03-15 13:30:49