11

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.

5
  • 1
    Why are you rolling your own database tables? Your life would be much simpler if you implemented your custom content as a Custom Post Type. Jan 29, 2013 at 15:10
  • I actually thought that this question would come. I develop this plugin to get to know Wordpress, so I first didn't know about Custom Post Types. I have two database tables, one for the courses and one for the course categories. One category can have several courses, so the two tables are linked. I don't think it's that easy to accomplish it with Custom Post Types. Sure I could use Custom Taxonomies for the courses, but I would have to add more fields, because a course category does not just have name. Just for now it's much easier to do it with custom database tables.
    – Gchtr
    Jan 29, 2013 at 19:23
  • 1
    Your use case is the exact, intended use case for Custom Post Types and Custom Taxonomies. You may be misunderestimating the elegance, flexibility, and power of CPTs and Custom Taxonomies. Jan 29, 2013 at 19:25
  • It’s indeed possible that I do. I should probably just try. Thanks for the advice.
    – Gchtr
    Jan 29, 2013 at 19:30
  • in_the_loop() is set to true whenever the_post() is fired. Without digging too deeply into core, and knowing that nav menus are themselves loops, I'm guessing that somewhere along the way, wp_nav_menu() instantiates a loop, causing in_the_loop() to return true. Jan 30, 2013 at 14:22

4 Answers 4

5

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.

9
  • That didn't work for now. But I refined my question, because it might not have been specific enough. Maybe the problem lies somewhere else.
    – Gchtr
    Jan 30, 2013 at 13:46
  • What do you mean by "that didn't work for now"? What exactly did you try? What did you expect to happen, that didn't, or what happened unexpectedly? Jan 30, 2013 at 14:05
  • See updated answer, that should address the nav menu item titles. Jan 30, 2013 at 14:31
  • I said that because I think your answer might be the right one (pushing in the right direction), but that I maybe didn't ask my question clear enough. get_post_meta( $id, '_wp_page_template', true ) returns default and I don't know what to do with this. When I set 'page-courses.php' to 'default', all the nav links change, except when I hook the the_title filter to loop_start, then only the footer links change. I checked which template file is used, and it's 'page-courses.php' and not 'page.php' (which I thought might be the default one).
    – Gchtr
    Jan 30, 2013 at 15:46
  • So, is "Courses" the name of your static page? Jan 30, 2013 at 16:24
1

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
  • 1
    How would that work, under the assumption that the code in question uses the_title()? Code examples? Jan 29, 2013 at 17:54
  • @ChipBennett, I don't understand the question. If he needs the filter to be applied only for page with a specific template then he can place the same code in the template before calling get_header(). Jan 29, 2013 at 19:25
  • Yes, actually I too think this would work. However, I think I would have to take the detour to set a variable in the plugin that would be available in query_vars? So for me, filtering the_title is a nicer solution.
    – Gchtr
    Jan 30, 2013 at 17:19
1

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.