user147215
user147215

Reputation:

Set page title in WordPress with PHP

I know this question has been asked thousands of times before, but I have attempted a lot of these solutions without any success.

Attempted solutions, among others (added to the template page)

add_filter('the_title','callback_to_set_the_title');

add_filter('wp_title', 'callback_to_set_the_title');

global $title;
$title = 'My Custom Title';

add_filter( 'pre_get_document_title', 'callback_to_set_the_title' );

add_filter( 'document_title_parts', 'callback_to_set_the_title' );

The scenario is that I have a custom template for a job listing page. This page has URL rewriting in place that rewrites domain.com/about/careers/search/job?slug=whatever to domain.com/about/careers/search/job/whatever - the slug is used to retrieve an entry from Redis that contains all the information for the job listing including the title I'd like to use.

Here's how I am rewriting the URL (from functions.php):

function job_listing_url_rewrite() {
    global $wp_rewrite;
    add_rewrite_tag('%slug%', '([^&]+)');
    add_rewrite_rule('^about/careers/search/job/([a-zA-Z0-9-_]+)/?', 'index.php?page_id=6633&slug=$matches[1]', 'top');
    $wp_rewrite->flush_rules(true);
}
add_action('init', 'job_listing_url_rewrite', 10, 0);

Upvotes: 12

Views: 16880

Answers (6)

Vadim H
Vadim H

Reputation: 767

add_filter( 'document_title', 'mod_browser_tab_title');
function mod_browser_tab_title( $title )
{
    $title = 'Custom title';
    return $title;
}

Upvotes: 1

Jhon Doe
Jhon Doe

Reputation: 31

I'm having the same issue.

After debugging wp source code. I found a nicer solution. wp_get_document_title() Based on comments, we can use these filters in wp 4.4.0 or abouve.

/**  Replace document title **/
function product_page_replace_title( $empty ) {
    // New page title.
    return 'New Title';
}
add_filter( 'pre_get_document_title', 'product_page_replace_title' );

Upvotes: 3

Cameron Hurd
Cameron Hurd

Reputation: 5031

I suspect that the logic for altering wp_title in the template is firing too late.

In most cases, wp_title is invoked in the header file, which will have been processed before getting to the template with your logic.

If you add the following to your functions.php file, WordPress will set the title the way you intend.

<?php
// functions.php

function change_title_if_job_posting($query) {
    $slug = $query->query->get('slug');

    // The URL is a match, and your function above set the value of $slug on the query
    if ('' !== $slug) {
        /**
         * Use the value of $slug here and reimplement whatever logic is
         * currently in your template to get the data from Redis.
         *
         * For this example, we'll pretend it is set to var $data. :)
         */
        $data = 'whatever-the-result-of-the-redis-req-and-subsequent-processing-is';

        /**
         * Changes the contents of the <title></title> tag.
         *
         * Break this out from a closure to it's own function
         * if you want to also alter the get_the_title() function
         * without duplicating logic!
         */
        add_filter('wp_title', function($title) use ($data) {
            return $data;
        });
    }
}

// This is the crux of it – we want to try hooking our function to the wp_title
// filter as soon as your `slug` variable is set to the WP_Query; not all the way down in the template.
add_action('parse_query', 'change_title_if_job_posting');

This will only add the function to the filter when the main WP_Query has a variable set on it called "slug", which should coincide with the logic you laid out above.

Upvotes: 4

scytale
scytale

Reputation: 1399

From the question and comments, I assume you are using a custom page template (probably in a child theme & based on page.php) and not a custom post type?

I similarly use a custom page with a non-WordPress database to display requested content (generating Title, plus unique meta tags for Google on the fly) e.g., http://travelchimps.com/country/france (?cc=france Title "France: travel advice") and travelchimps.com/country/cuba/health ( ?cc=cuba&spg=health "Cuba travel info: Health".)

I may be missing something in your question, but with a custom page template you do not need filters/WordPress functionality for page title. You can use your own variable direct. If you need a meaningful index page of joblist titles you can also generate this direct from Redis.

File functions.php:

// Allow WordPress to store querystring attributes for use in our pages
function my_query_vars_filter($vars) {
  # Jobs
  $vars[] .= 'slug';
  # More variables
}
add_filter('query_vars', 'my_query_vars_filter');

Custom page template:

<?php /* Template Name: JobQryPage*/

// *** Get data (I don't know Redis)  ***
$redisKey = get_query_var('slug');  // Validate as reqd

// Use $redisKey to select $jobInfo from Redis
$PAGE_TITLE = $jobInfo['title']; // Or whatever

// Maybe some meta tag stuff

// Code copied from page.php ....
   // Maybe replace "get_header();" with modified header.php code
   ...
   // ** IN THE HTML FOR THE TITLE: CHANGE say "the_title();" to  "echo $PAGE_TITLE;" **
   // e.g. ?>
    <h2 class="post-title"><?php echo $PAGE_TITLE; ?></h2>
   ...
  <div class="post-content">
    <?php // ** delete "< ?php the_content(); ? > or other code used to display page editor content
          // and replace with your code to render your Redis $jobInfo ** ?>
  </div>
  <!-- remainder of page.php code -->

The disadvantage of custom page template is it is "theme specific" - however it is a simple matter to create a new (same name template) using new theme's page.php as a base and copy in code from your old template.

I also prefer to use names to id's. So I used the page editor to save an empty page (title and slug of country) with "CountryQryPage" selected as template; and in my site-functions plugin:

function tc_rewrite_rules($rules) {
  global $wp_rewrite;
  $tc_rule = array(
    'country/(.+)/?' => 'index.php?pagename=' . 'country' . '&cc=$matches[1]'
  );
  return array_merge($tc_rule, $rules);
}
add_filter('page_rewrite_rules', 'tc_rewrite_rules');

Upvotes: -1

Faham Shaikh
Faham Shaikh

Reputation: 993

I understand that you have already tried using the wp_title filter, but please try it the following way.

function job_listing_title_override ($title, $sep){
    if (is_page_template('templates/job-listing.php')) {
        $title = 'Job Listing Page '.$sep.' '. get_bloginfo( 'name', 'display' );
    }
    return $title;
}
add_filter( 'wp_title', 'job_listing_title_override', 10, 2 );

Upvotes: 3

Kapsonfire
Kapsonfire

Reputation: 1033

I did some research with my template. My template calls get_header() to print the HTML tags with head and so on, and I guess yours does the same.

To replace the title, I start a output buffering right before calling that function and get it afterwards.

After that, I can replace the title easily with preg_replace():

ob_start();
get_header();
$header = ob_get_clean();
$header = preg_replace('#<title>(.*?)<\/title>#', '<title>TEST</title>', $header);
echo $header;

Upvotes: 12

Related Questions