user7259161
user7259161

Reputation:

Overwrite title tag using a Wordpress plugin

I am trying to overwrite the <title> tag of a page using a Wordpress plugin. I don't want to change the theme's code. I just wanna force the theme to change some page titles via the plugin.

The theme uses add_theme_support( 'title-tag' ). Note that the use of wp_title is now deprecated.

Upvotes: 0

Views: 1993

Answers (2)

snnsnn
snnsnn

Reputation: 13620

I posted this answer for another question but since it is relevant and more up-to-date, I though it might be useful for some people.

How document title is generated has changed since Wordpress v4.4.0. Now wp_get_document_title dictates how title is generated:

/**
 * Displays title tag with content.
 *
 * @ignore
 * @since 4.1.0
 * @since 4.4.0 Improved title output replaced `wp_title()`.
 * @access private
 */
function _wp_render_title_tag() {
    if ( ! current_theme_supports( 'title-tag' ) ) {
        return;
    }

    echo '<title>' . wp_get_document_title() . '</title>' . "\n";
}

Here is the code from v5.4.2. Here are the filters you can use to manipulate title tag:

function wp_get_document_title() {
    /**
    * Filters the document title before it is generated.
    *
    * Passing a non-empty value will short-circuit wp_get_document_title(),
    * returning that value instead.
    *
    * @since 4.4.0
    *
    * @param string $title The document title. Default empty string.
    */
    $title = apply_filters( 'pre_get_document_title', '' );
    if ( ! empty( $title ) ) {
        return $title;
    }
    // --- snipped ---
    /**
    * Filters the separator for the document title.
    *
    * @since 4.4.0
    *
    * @param string $sep Document title separator. Default '-'.
    */
    $sep = apply_filters( 'document_title_separator', '-' );

    /**
    * Filters the parts of the document title.
    *
    * @since 4.4.0
    *
    * @param array $title {
    *     The document title parts.
    *
    *     @type string $title   Title of the viewed page.
    *     @type string $page    Optional. Page number if paginated.
    *     @type string $tagline Optional. Site description when on home page.
    *     @type string $site    Optional. Site title when not on home page.
    * }
    */
    $title = apply_filters( 'document_title_parts', $title );
    // --- snipped ---
    return $title;
}

So here are two ways you can do it.

First one uses pre_get_document_title filter which short-circuits the title generation and hence more performant if you are not going make changes on current title:

function custom_document_title( $title ) {
    return 'Here is the new title';
}
add_filter( 'pre_get_document_title', 'custom_document_title', 10 );

Second way uses document_title_separator and document_title_parts hooks for the title and the title seperator that are executed later in the function, after title is generated using functions like single_term_title or post_type_archive_title depending on the page and about to be outputted:

// Custom function should return a string
function custom_seperator( $sep ) {
   return '>';
}
add_filter( 'document_title_separator', 'custom_seperator', 10 );

// Custom function should return an array
function custom_html_title( $title ) {
   return array(
     'title' => 'Custom Title',
     'site'  => 'Custom Site'
    );
}
add_filter( 'document_title_parts', 'custom_html_title', 10 );

Upvotes: 0

Chandra Kumar
Chandra Kumar

Reputation: 4205

Your problem is that you can not use wp_title() in the theme if the theme already supports title-tag. The <head> of your theme should look like this:

<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <?php wp_head(); ?>
</head>

The filter and title-tag support:

add_action( 'after_setup_theme', 'my_theme_functions' );
function my_theme_functions() {
    add_theme_support( 'title-tag' );
}

add_filter( 'wp_title', 'custom_titles', 10, 2 );
function custom_titles( $title, $sep ) {

    //set custom title here
    $title = "Some other title" . $title;;
    return $title;
}

If you do this, it will work perfectly.

Upvotes: 3

Related Questions