Применить фильтр the_title () в post & название страницы, но не в заголовке меню

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

Я хочу изменить заголовок сообщений и страниц в: домашней странице , всех архивных страницах и всех виджетах (последние сообщения, случайный почтовый виджет и т. д.)

Аналогичные вопросы возникают как в Stack Overflow, так и в WP Stack Exchange, предлагая использовать функцию in_the_loop(). К сожалению, это не работает для меня, потому что, если я его помещаю, это также влияет на виджеты боковой панели.

Это означает, что если я использую функцию in_the_loop(), the_title не влияет на recent posts widget, random post widget и т. д.

Итак, как я могу применить фильтр the_title только для post и page, но не названия меню?

function pppp_title_update( $title, $id = null ) {

    if ( ! is_admin() ) {
       if(is_singular(array('post','page')) || is_archive() || is_home()){
            if(in_the_loop()){
                $current_post_id = get_the_ID();
                $new_titile = get_post_meta($current_post_id, 'pp_new_title',true);
                return $new_titile;  
            }                     
       } 
    }

    return $title;
}
add_filter( 'the_title', 'pppp_title_update', 10, 2 );
5 голосов | спросил Ranuka 21 J000000Saturday18 2018, 05:33:29

3 ответа


5

Описание проблемы:

Позвольте мне сначала перефразировать вопрос. Вы хотите:

  1. Установите новый заголовок для всех post и page из мета-поля.

  2. Вы хотите, чтобы это произошло везде (домашняя страница, одна страница, виджеты и т. д.).

  3. Однако вы не хотите, чтобы это изменение названия происходило, если заголовок находится в меню навигации.

Решение:

Прежде чем дать вам КОД, позвольте мне сначала объяснить несколько моментов (основанный на вашем коде):

Как изменить заголовки всех сообщений и страниц:

Вы уже знаете использование фильтра the_title. Однако, если вы хотите настроить таргетинг на все post и page (но не пользовательские типы сообщений), то ваше условие:

is_singular(array('post','page')) || is_archive() || is_home()

не будет работать. Например, он изменит тип персонализированного сообщения на странице архива или на домашней странице. Это условие не проверяет, является ли заголовок, который мы фильтруем, page или post. Вместо этого он проверяет, является ли сама страница единственной (post или page), или это страница архива (категория, тег и т. д.) или домашняя страница. Поэтому настраиваемые типы сообщений на этих страницах также затрагиваются. Кроме того, если на странице пользовательского типа сообщений (единственная) есть виджет, то по этой логике page или post в этом виджетах не будут затронуты.

Чтобы исправить это, нам нужна другая проверка, например:

$post = get_post( $id );
if ( $post instanceof WP_Post && ( $post->post_type == 'post' || $post->post_type == 'page' ) )

Почему название меню навигации также изменено & как остановить его:

WordPress применяет фильтр the_title дважды в заголовке пунктов меню навигации (если пункты меню соответствуют существующим сообщениям или страницам).

  1. Сначала как соответствующее сообщение или заголовок страницы. Это происходит в wp_setup_nav_menu_item() функция wp-includes/nav-menu.php файл.

  2. Затем в качестве названия элемента меню. Это происходит в классе Walker_Nav_Menu.

Для вашего требования нам нужно остановить фильтр the_title.

К счастью, WordPress имеет два фильтра: pre_wp_nav_menu срабатывает перед фильтрованием названий меню и wp_nav_menu_items срабатывает после фильтрации заголовков меню. Поэтому мы можем использовать эти два фильтра, чтобы сначала удалить фильтр the_title для заголовков пунктов меню навигации, а затем добавить the_title снова отфильтровать остальные заголовки.

CODE

Вы можете использовать следующий код в файле functions.php или в виде отдельного плагина:

function wpse309151_title_update( $title, $id = null ) {
    if ( ! is_admin() && ! is_null( $id ) ) {
        $post = get_post( $id );
        if ( $post instanceof WP_Post && ( $post->post_type == 'post' || $post->post_type == 'page' ) ) {
            $new_titile = get_post_meta( $id, 'pp_new_title', true );
            if( ! empty( $new_titile ) ) {
                return $new_titile;
            }
        }
    }
    return $title;
}
add_filter( 'the_title', 'wpse309151_title_update', 10, 2 );

function wpse309151_remove_title_filter_nav_menu( $nav_menu, $args ) {
    // we are working with menu, so remove the title filter
    remove_filter( 'the_title', 'wpse309151_title_update', 10, 2 );
    return $nav_menu;
}
// this filter fires just before the nav menu item creation process
add_filter( 'pre_wp_nav_menu', 'wpse309151_remove_title_filter_nav_menu', 10, 2 );

function wpse309151_add_title_filter_non_menu( $items, $args ) {
    // we are done working with menu, so add the title filter back
    add_filter( 'the_title', 'wpse309151_title_update', 10, 2 );
    return $items;
}
// this filter fires after nav menu item creation is done
add_filter( 'wp_nav_menu_items', 'wpse309151_add_title_filter_non_menu', 10, 2 );
ответил Fayaz 24 J000000Tuesday18 2018, 06:08:44
3

Редактор навигации WordPress имеет возможность изменять название меню независимо от заголовка сообщения /страницы.

Если вам понадобится более автоматический код решения ниже, замените заголовок публикации /страницы всюду, используя фильтр the_title, но восстановите название по умолчанию для с помощью фильтра nav_menu_item_title.

/**
 * Replace post/page title on home, single and archive pages.
 *
 * @param string $title   Post title
 * @param int    $post_id Post ID
 *
 * @return string New post tilte
 */
function wpse_309151_get_replace_default_title_from_meta( $title, $post_id ) {

    $post_type = get_post_type( $post_id );

    if( !is_admin() && ( $post_type === 'post' || $post_type === 'page' ) ) {

        $new_title = get_post_meta( $post_id, 'wpse_309151_post_title', true);

        if( $new_title && !empty( $new_title ) ) {
            return $new_title;
        }
    }

    return $title;
}

add_filter( 'the_title', 'wpse_309151_get_replace_default_title_from_meta', 10, 2 );

/**
 * Restore default post/page title in navigation
 *
 * @param string   $title The menu item's title.
 * @param WP_Post  $item  The current menu item.
 * @param stdClass $args  An object of wp_nav_menu() arguments.
 * @param int      $depth Depth of menu item. Used for padding.
 *
 * @return string Restored post title
 */
function wpse_309151_get_restore_default_title_for_navigation( $title, $item, $args, $depth ) {

    // Remove filter to not affect title
    remove_filter( 'the_title', 'wpse_309151_get_replace_default_title_from_meta', 10, 2 );

    $post_id = $item->object_id;
    $title   = get_the_title( $post_id );

    // Add the title filter back
    add_filter( 'the_title', 'wpse_309151_get_replace_default_title_from_meta', 10, 2 );

    return $title;
}

add_filter( 'nav_menu_item_title', 'wpse_309151_get_restore_default_title_for_navigation', 10, 4 );
ответил motivast 23 J000000Monday18 2018, 13:16:56
-1

Если у вас есть объект post (get_the_ID () или $ post-> ID, по существу то же самое) См. https://stackoverflow.com/questions/22351038/get-the-current-page-id-inside-wordpress-plugin-page , тогда вы также должны иметь возможность использовать https://developer.wordpress.org/reference/functions /get_post_type /, чтобы проверить тип или

if (in_array($post->post_type, array('post', 'page')) {
... swop the title
}
ответил anmari 21 J000000Saturday18 2018, 07:10:01

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132