web-dev-qa-db-fra.com

Appliquez le filtre the_title () dans le titre de l'article et de la page, mais pas dans le titre du menu

J'utilise le code suivant pour changer le titre de WordPress posts et pages . Mais cela change aussi les titres des éléments de menu de navigation, ce que je veux éviter.

Je souhaite modifier le titre des publications et des pages dans: page d'accueil , toutes pages d'archives et toutes widgets (widget de publications récentes, widget de publication aléatoire, etc.)

Il existe des questions similaires dans Stack Overflow et WP Stack Exchange suggérant d'utiliser la fonction in_the_loop(). Malheureusement, cela ne fonctionne pas pour moi, car si je le place, cela affecte également les widgets de la barre latérale.

Cela signifie que si j'utilise la fonction in_the_loop(), le filtre the_title n'affecte pas recent posts widget, random post widget etc.

Alors, comment puis-je appliquer le filtre the_title pour seulement les titres post et page, mais pas pour les titres de menu?

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 );
7
Ranuka

Description du problème:

Permettez-moi de reformuler la question en premier. Tu veux:

  1. Définissez le nouveau titre sur tous les types post et page à partir d'un champ méta.

  2. Vous voulez que cela se produise partout (page d'accueil, page simple, widgets, etc.)

  3. Cependant, vous ne voulez pas que ce titre change si le titre est dans le menu de navigation.

Solution:

Avant de vous donner le code, laissez-moi d'abord expliquer quelques points (basés sur votre code):

Comment changer les titres de tous les posts et pages:

Vous connaissez déjà l'utilisation du filtre the_title. Toutefois, si vous souhaitez cibler tous les titres de types post et page (mais pas les types de publication personnalisés), votre condition:

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

ne fonctionnera pas. Par exemple, cela modifiera également le type de publication personnalisé sur une page d'archive ou sur la page d'accueil. Cette condition ne vérifie pas si le titre que nous filtrons est un type page ou post. Au lieu de cela, il vérifie si la page elle-même est soit singulière (post ou page) ou s'il s'agit d'une page d'archive (catégorie, balise, etc.) ou de la page d'accueil. Les types de publication personnalisés dans ces pages sont donc également affectés. De plus, s'il existe un widget dans une page de type publication personnalisée (singulier), les titres page ou post de ce widget ne seront pas affectés dans cette logique.

Pour résoudre ce problème, nous avons besoin d'une vérification différente, telle que:

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

Pourquoi le titre du menu de navigation est également modifié et comment l’arrêter:

WordPress applique le filtre the_title deux fois sur le titre des éléments du menu de navigation (si les éléments du menu correspondent à des publications ou à des pages existantes).

  1. D'abord en tant que titre de l'article ou de la page correspondant. Cela se produit dans la fonction wp_setup_nav_menu_item() du fichier wp-includes/nav-menu.php.

  2. Ensuite, comme le titre de l'élément de menu lui-même. Cela se produit dans la classe Walker_Nav_Menu.

Pour votre besoin, nous devons arrêter le filtre the_title à la fois.

Heureusement, WordPress a deux filtres: pre_wp_nav_menu se déclenche avant de filtrer les titres de menu et wp_nav_menu_items se déclenche après de filtrer les titres de menu. Nous pouvons donc utiliser ces deux filtres pour supprimer d’abord le filtre the_title des titres d’éléments de menu de navigation, puis rajouter le filtre the_title pour les autres titres.

CODE

Vous pouvez utiliser le code suivant dans le fichier functions.php du thème ou en tant que plug-in séparé:

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 );
11
Fayaz

L'éditeur de navigation WordPress a la possibilité de changer le titre du menu indépendamment du titre du message/de la page.

Si vous avez besoin d'un code de solution plus automatisé, le code ci-dessous remplacera le titre de l'article/de la page partout en utilisant le filtre the_title, mais restaurera le titre par défaut de l'élément de menu en utilisant le filtre 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 );
3
kierzniak