Change the_title() of a page dynamically

The question:

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

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.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

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

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

Method 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;
}

Method 4

Try using conditional tags to ensure the_title() is only being modified on the pages that you want.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment