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

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

Related posts

Leave a Reply

4 comments

  1. 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.

  2. 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>";
    
  3. 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…

  4. 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' );