Wenden Sie den Filter_title () im Beitrags- und Seitentitel an, jedoch nicht im Menütitel

8

Ich verwende den folgenden Code, um den Titel von WordPress- Posts und -Seiten zu ändern . Aber es ändert auch die Titel der Navigationsmenüelemente, die ich vermeiden möchte.

Ich möchte den Titel von Posts und Seiten in ändern: Homepage , alle Archivseiten und alle Widgets (Widget für aktuelle Posts, Widget für zufällige Posts usw.)

Sowohl im Stapelüberlauf als auch im WP-Stapelaustausch gibt es ähnliche Fragen, die die Verwendung der in_the_loop()Funktion vorschlagen . Leider funktioniert es bei mir nicht, denn wenn ich es platziere, wirkt es sich auch auf die Seitenleisten-Widgets aus.

Das heißt, wenn ich in_the_loop()Funktion, the_titleFilter wirkt sich nicht auf recent posts widget, random post widgetusw.

Wie kann ich also the_titleFilter für Nur postund pageTitel anwenden , aber nicht für Menütitel?

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 );
Ranuka
quelle
Haben Sie z. B. if( ! is_nav_menu_item( $id ) ){ ... }innerhalb Ihres Filterrückrufs versucht , das Filtern des Titels von Navigationsmenüelementen zu vermeiden?
Birgire
1
if( ! is_nav_menu_item( $id ) )Mit check wird ein benutzerdefinierter Link zum Navigationsmenüelement ausgeschlossen. Wenn es sich bei dem Navigationsmenüelement selbst jedoch um eine Seite oder einen Beitrag handelt, wird er zweimal mit dem the_titleFilter gefiltert . In diesem Fall funktioniert diese Bedingung nur einmal (dh nicht, wenn the_titlezum Filtern des ursprünglichen Beitrags- / Seitentitels im Menü ausgelöst wird).
Fayaz

Antworten:

16

Problembeschreibung:

Lassen Sie mich zuerst die Frage umformulieren. Du möchtest:

  1. Setzen Sie allen einen neuen Titel postund geben Sie ihn pageaus einem Metafeld ein.

  2. Sie möchten, dass dies überall geschieht (Startseite, einzelne Seite, Widgets usw.)

  3. Sie möchten jedoch nicht, dass diese Titeländerung erfolgt, wenn sich der Titel im Navigationsmenü befindet.

Lösung:

Bevor ich Ihnen den CODE gebe, möchte ich zunächst einige Punkte erläutern (basierend auf Ihrem CODE):

So ändern Sie die Titel aller Beiträge und Seiten:

Sie kennen die Verwendung von the_titleFiltern bereits. Wenn Sie jedoch auf alle Titel abzielen postund pagediese eingeben möchten (jedoch keine benutzerdefinierten Beitragstypen), gilt folgende Bedingung:

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

wird nicht funktionieren. Beispielsweise wird der benutzerdefinierte Beitragstyp auf einer Archivseite oder der Startseite geändert. Diese Bedingung prüft nicht, ob der Titel, den wir filtern, ein pageoder ein postTyp ist. Stattdessen wird überprüft, ob die Seite selbst entweder eine Singular- ( postoder page) oder eine Archivseite (Kategorie, Tag usw.) oder die Startseite ist. Daher sind auch benutzerdefinierte Beitragstypen auf diesen Seiten betroffen. Wenn sich auf einer benutzerdefinierten Post-Typ-Seite (Singular) ein Widget befindet, sind diese Logik pageoder postTitel in diesem Widget dort nicht betroffen.

Um dies zu beheben, benötigen wir eine andere Prüfung, wie zum Beispiel:

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

Warum der Titel des Navigationsmenüs ebenfalls geändert wird und wie Sie ihn stoppen können:

WordPress wendet den the_titleFilter zweimal auf den Titel der Navigationsmenüelemente an (wenn die Menüelemente vorhandenen Posts oder Seiten entsprechen).

  1. Zuerst als entsprechender Beitrags- oder Seitentitel. Dies geschieht in der wp_setup_nav_menu_item()Funktion der wp-includes/nav-menu.phpDatei.

  2. Dann als Menüelementtitel selbst. Dies geschieht in der Walker_Nav_MenuKlasse.

Für Ihre Anforderung müssen wir den the_titleFilter beide Male stoppen .

Glücklicherweise hat WordPress zwei Filter: pre_wp_nav_menuBrände vor dem Filtern von Menütiteln und wp_nav_menu_itemsBrände nach dem Filtern von Menütiteln. Mit diesen beiden Filtern können wir also zuerst den the_titleFilter für Titel von Navigationsmenüelementen entfernen und dann den the_titleFilter für andere Titel wieder hinzufügen .

CODE

Sie können den folgenden CODE in der functions.phpThemendatei oder als separates Plugin verwenden:

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
quelle
1
Danke für die ausführliche Antwort. Scheint so, als würde das gut funktionieren. Nochmals vielen Dank ... Aber ich bin auf einer Reise. Ich werde Ihre Antwort an diesem Freitag überprüfen und Ihnen das Ergebnis mitteilen.
Ranuka
Das ist in Ordnung, nehmen Sie sich Zeit.
Fayaz
1
Dies funktioniert ohne Probleme. Danke für die Antwort und Erklärung :-)
Ranuka
4

Der WordPress-Navigationseditor kann den Menütitel unabhängig vom Titel des Beitrags / der Seite ändern.

Wenn Sie mehr automatisierten Lösungscode benötigen, wird der Titel des Beitrags / der Seite überall mithilfe des the_titleFilters ersetzt, der Standardtitel des Menüelements wird jedoch mithilfe des Filters wiederhergestellt 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 );
kierzniak
quelle