How do you add_filter to only one instance of the_title()

2.9k views Asked by At

I created a filter that modifies the_title() of a post, but the problem I'm having is that it's modifying every instance of the_title(). I got most of the problem sorted out with the in_the_loop() function, however any theme that has "next post" "previous post" navigation links within the loop are still having the filter applied (understandably so). How can I apply the filter to only the the_title() of the current post?

function xyz_the_title( $the_title ) {

    if( !in_the_loop() )
        return $the_title;

    $location = get_post_meta( get_the_ID(), 'location', true );

    $the_title .= ' - ' . $location;

    return $the_title;  

}

add_filter( 'the_title', 'xyz_the_title' );
4

There are 4 answers

2
SamotnyPocitac On

do it with jQuery

Something like this should do the trick:

$(document).ready(function() {
    $('#entry-header').text(function(i, oldText) {
        return oldText === 'Popular Science' ? 'New word' : oldText;
    });
});

This only replaces the content when it is Popular Science. See text in the jQuery API.

1
BoragThungg On

Rather than filtering the_title you could edit your template file instead and append the location to your returned the_title().

            echo "<h1>" . get_the_title() . " - " . $location . "</h1>";
1
BoragThungg On

Ah, didn't know it was for a plugin. In which case, I think you should be ok to use if_filter then. This checks whether the filter has been run x times on the page in question. So, we check if it has run once on the page and if so it won't run again. Also, I have assumed you only want this to run on single post pages. This is untested.

function xyz_the_title( $the_title ) {

    if( is_single() AND did_filter('the_title') === 1 ) {

        if( !in_the_loop() )
            return $the_title;

        $location = get_post_meta( get_the_ID(), 'location', true );
        $the_title .= ' - ' . $location;
        return $the_title;  
    }
}
add_filter( 'the_title', 'xyz_the_title' );
1
Craig Wayne On

Ran into a similar situation and was hoping this thread could save me...

Anyways this is what I managed to do thus far in

add_filter( 'the_title', function( $title, $id ){
    /**
     * don't run in the backend
     */
    if( is_admin() ) {
        return $title;
    }


    /**
     * invalid values received
     */
    if( empty( $title ) || $id < 1 ){
        return $title;
    }


    global $post;
    if ( ! $post instanceof WP_Post ){
        return $title;
    }


    /**
     * PREVENTATIVE MEASURE...
     * only apply the filter to the current page's title,
     * and not to the other title's on the current page
     */
    global $wp_query;
    if( $id !==  $wp_query->queried_object_id ){
        return $title;
    }

    /**
     * Don't run this filter if wp_head calls it
     */
    if( doing_action( 'wp_head' ) ){
        return $title;
    }

    return 'MODIFIED - '.$title;
});

Here are the shortfalls:

  1. If you have the same post being displayed on the current page, somewhere else, it's gonna modify THAT post title as well

Currently thinking about having a look at the call stack to detect if the call is coming from the theme...

but I would suggest you find another solution bud...