Change the_title() of a page dynamically

I’m developing a plugin that doesn’t use a custom post type, but separate database tables.
It’s a plugin that displays a list of courses with links that lead to the different course detail pages, where the user then can subscribe for a course.

In the current state, I’m using a shortcode to get the plugins data into a page with a custom page template (page-courses.php).

Read More

I now want to change the_title() dynamically, according to the page that the plugin shows (list of courses, course details page with forms, form submission success page). But whenever I do that with the following filter, the links to other pages in the footer also change:

<?php
 
add_filter('the_title', 'custom_page_title');
function custom_page_title() {
    return 'Custom Title';
}

Edit

In the footer.php I have a function that includes footer links with wp_nav_menu() so I can define them in Appearance > Menus. But with the filter above, all the links in the footer also change to ‘Custom Title’. But I just want to change the title of the page, not affecting menu links in the footer.

Trying to add a conditional tag in_the_loop() the footer links are still affected, although they are not in the loop.

<?php

add_action( 'loop_start', 'set_custom_title' );
function set_custom_title() {
    if ( in_the_loop() ) {
        add_filter( 'the_title', 'custom_page_title' );
    }
}

function custom_page_title() {
    return 'Custom Title';
}

It’s similar to this question: filter the_title problem in nav, just that the links affected are in the footer and in_the_loop() doesn’t work.

How I can I change the_title() while only affecting the title of the current page being shown not affecting links in the footer?

Edit 2 – Solution

So I finally got it working:

<?php

add_action( 'loop_start', 'set_custom_title' );
function set_custom_title() {
    add_filter( 'the_title', 'wpse83525_filter_the_title', 10, 2 );
}

function wpse83525_filter_the_title( $title, $id ) {
    if ( 'page-listcourses.php' == get_post_meta( $id, '_wp_page_template', true ) ) {
        return 'Custom Title';
    }
    return $title;
}

The file page-listcourses.php is a Custom Post Template that I assigned to the static page named ‘Courses’.

I assume it didn’t work before because the name of the static page and filename of the Custom Post Template were the same.

Related posts

Leave a Reply

4 comments

  1. I would use the is_page_template() conditional:

    if ( is_page_template( 'page-courses.php' ) ) {
        // The current page uses your
        // custom page template;
        // do something
    }
    

    Edit

    You would use this conditional inside your filter callback:

    function wpse83525_filter_the_title( $title ) {
        if ( is_page_template( 'page-courses.php' ) ) {
            return 'Custom Title';
        }
        return $title;
    }
    add_filter( 'the_title', 'wpse83525_filter_the_title' );
    

    Now, to isolate only the titles of pages that use your page template, you can take advantage of the other parameter passed to the_title: $id. Since you know the Id of the post for which the title is being filtered, you can query the _wp_page_template post meta, and ensure that it equals your page template:

    function wpse83525_filter_the_title( $title, $id ) {
        if ( 'page-courses.php' == get_post_meta( $id, '_wp_page_template', true ) ) {
            return 'Custom Title';
        }
        return $title;
    }
    add_filter( 'the_title', 'wpse83525_filter_the_title', 10, 2 );
    

    Edit 2

    If you want to target the “Courses” page specifically, use is_page() with the page slug 'courses', or the page title of 'Courses':

    function wpse83525_filter_the_title( $title ) {
        if ( is_page( 'Courses' ) ) {
            return 'Custom Title';
        }
        return $title;
    }
    add_filter( 'the_title', 'wpse83525_filter_the_title' );
    

    Though, I would recommend changing page-courses.php into a Custom Page Template, which would make this whole process much more robust.

  2. While is_page_template() will work, I prefer to put this kind of code in the page template itself to have all the code that generates this kind of page in one file.

  3. If you only want to edit the current page title, use the in_the_loop()conditional, as in:

    add_filter( 'the_title', 'modify_onpage_title', 10, 2);
    
    function modify_onpage_title( $title , $id = null ) {
    
        if(!in_the_loop()){
            // returns early if not relevant (as in custom menu loops)
            return $title;
        }
    
        // Tweak your title
        $title = "Yolo! ". $title;
        return $title;
    }