admin管理员组

文章数量:1277896

First, is it even possible to change the page title from a plugin (specifically, from a shortcode defined in a plugin)? This answer says no, but there are certainly reasonable use cases for it. Like, say, my use case (the shortcode displays detail page content for an item of a collection ... so, I put the shortcode on a page; what's the page title supposed to be? It depends on the detail item.).

I have tried every method I can find:

$_SESSION['custom_page_title'] = $eventData['eventtitle'];


//attempt 1
add_filter('document_title_parts', 'my_custom_title');
function my_custom_title( $title ) {
  // $title is an array of title parts, including one called `title`

  $title['title'] = stripslashes($_SESSION['custom_page_title']);

  return $title;
}


//attempt 2
add_filter("pre_get_document_title", "my_callback");
function my_callback($old_title){
    return stripslashes($_SESSION['custom_page_title']);
}


//attempt 3
add_filter('the_title','some_callback');
function some_callback($data){
    return stripslashes($_SESSION['custom_page_title']);

}


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

    //Check if custom titles are enabled from your option framework
    if ( ot_get_option( 'enable_custom_titles' ) === 'on' ||  (1 == 1)) {
        $title = stripslashes($_SESSION['custom_page_title']);
    }

    return $title;
}

But none of them work (with default twentytwentyone theme).

The plugin is a custom one made by me. The use case is simply to change the page title, based on data that the plugin knows. It's pretty simple in concept. Not really another way to do it.

The shortcode defined in the plugin is displaying the detail for one specific entity (something like /individual_display?id=5 ) and the page should be titled accordingly. The page shouldn't be titled "Individual Display" or whatever, it should be titled "Actual Name of The Individual Thing That Happens to Have ID #5"

Is it possible, and if so, how?

First, is it even possible to change the page title from a plugin (specifically, from a shortcode defined in a plugin)? This answer says no, but there are certainly reasonable use cases for it. Like, say, my use case (the shortcode displays detail page content for an item of a collection ... so, I put the shortcode on a page; what's the page title supposed to be? It depends on the detail item.).

I have tried every method I can find:

$_SESSION['custom_page_title'] = $eventData['eventtitle'];


//attempt 1
add_filter('document_title_parts', 'my_custom_title');
function my_custom_title( $title ) {
  // $title is an array of title parts, including one called `title`

  $title['title'] = stripslashes($_SESSION['custom_page_title']);

  return $title;
}


//attempt 2
add_filter("pre_get_document_title", "my_callback");
function my_callback($old_title){
    return stripslashes($_SESSION['custom_page_title']);
}


//attempt 3
add_filter('the_title','some_callback');
function some_callback($data){
    return stripslashes($_SESSION['custom_page_title']);

}


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

    //Check if custom titles are enabled from your option framework
    if ( ot_get_option( 'enable_custom_titles' ) === 'on' ||  (1 == 1)) {
        $title = stripslashes($_SESSION['custom_page_title']);
    }

    return $title;
}

But none of them work (with default twentytwentyone theme).

The plugin is a custom one made by me. The use case is simply to change the page title, based on data that the plugin knows. It's pretty simple in concept. Not really another way to do it.

The shortcode defined in the plugin is displaying the detail for one specific entity (something like /individual_display?id=5 ) and the page should be titled accordingly. The page shouldn't be titled "Individual Display" or whatever, it should be titled "Actual Name of The Individual Thing That Happens to Have ID #5"

Is it possible, and if so, how?

Share Improve this question edited May 6, 2021 at 19:00 GHolmes asked May 3, 2021 at 17:35 GHolmesGHolmes 636 bronze badges 5
  • 1 It's not possible from a shortcode, because the title has already been generated/output before the shortcode is ever run. Since you mentioned a plugin, I suggest talking to its authors. There might be a way that doesn't rely on the shortcode, but that would depend on the plugin. – Jacob Peattie Commented May 4, 2021 at 4:11
  • The plugin is a custom one made by me. The use case is simply to change the page title, based on data that the plugin knows. It's pretty simple in concept. Not really another way to do it. The plugin is displaying the detail for one specific entity (something like /individual_display?id=5 ) and the page should be titled accordingly. The page shouldn't be titled "Individual Display" or whatever, it should be titled "Actual Name of The Individual Thing That Happens to Have ID #5" – GHolmes Commented May 6, 2021 at 18:58
  • Did you check that: wordpress.stackexchange/questions/46707/… – איש נחמד Commented May 6, 2021 at 21:53
  • Do you only care for first occurrence of the shortcode? If its in the page multiple times, which one should be considered? – kero Commented Nov 10, 2021 at 16:22
  • The shortcode is only used one time on a page. It gets an id number from the querystring, it looks up data from a custom database table, and it displays it on the page. The logical thing to do would be to also change the page title to have the title of the item that was looked up. Like if it is /page?item=5 then we look in the db for item 5, among the data for it it's title is "Great Title", well, we should make the page title be "Great Title" – GHolmes Commented Nov 10, 2021 at 20:26
Add a comment  | 

2 Answers 2

Reset to default 3 +50

You can do it like so:

function filterDocumentTitle(string $title): string
{
    // don't change title on admin pages or when global $post is not loaded
    if (is_admin() || get_the_ID() === false) {
        return $title;
    }

    // don't change title if shortcode is not present in content
    if (!has_shortcode(get_the_content(), 'caption')) {
        return $title;
    }

    return 'special title';
}

add_filter('pre_get_document_title', 'filterDocumentTitle');

If you're using Yoast's SEO plugin, you'll also need add_filter('wpseo_title', 'filterDocumentTitle');, since the plugin doesn't play nicely with pre_get_document_title alone. Other SEO plugins might need similar fixes.

In the above code I check for [caption] shortcode, which I used locally to test it, replace this with your real shortcode name (without [ and ]).

With this you'll know when your shortcode is part of a page or not. Now what is left to do, is getting the value you want for your title. For lack of more information I'll assume that your shortcode looks something like this

add_shortcode('myshortcode', function () {
    $id = intval($_GET['item']);
    $eventData = /* .. get event data via ID */;
    return 'some contents depending on $eventData';
});

So that you don't have to duplicate your code, let's refactor this a bit to the following

function gholmesGetEventData(): array {
    if (empty($_GET['item'])) {
        throw new Exception('Only supported when item is provided.');
    }
    $id = intval($_GET['item']);
    $eventData = /* .. get event data via ID, throw Exception if not found */;
    return $eventData;
}

add_shortcode('myshortcode', function (): ?string {
    try {
        $eventData = gholmesGetEventData();
        return 'some contents depending on $eventData';
    } catch (Exception $e) {
        // do something with the exception
        return null;
    }
});

function gholmesFilterDocumentTitle(string $title): string
{
    // don't change title on admin pages or when global $post is not loaded
    if (is_admin() || get_the_ID() === false) {
        return $title;
    }

    // don't change title if shortcode is not present in content
    if (!has_shortcode(get_the_content(), 'caption')) {
        return $title;
    }

    try {
        $eventData = gholmesGetEventData();
        return $eventData['eventtitle'];
    } catch (Exception $e) {
        return $title;
    }
}

add_filter('pre_get_document_title', 'gholmesFilterDocumentTitle');

With this setup you'll call gholmesGetEventData() twice. Once in the title once in the shortcode body. To optimize this, you can use WordPress' object cache's set and get methods inside gholmesGetEventData() to minimize DB requests. (So the second call would just return the cached result.)

this code should do the trick, add it to your theme functions.php, or to your functions file in the plugin

add_filter("pre_get_document_title", "dynamic_page_title");
function dynamic_page_title(){
    if(isset($_SESSION['custom_page_title'])){
        return stripslashes($_SESSION['custom_page_title']);
    }
}

this will only change the page title for the pages that have a $_SESSION['custom_page_title'], the others pages title will remain the same. if the code isnt working you need to check if your page that change the products or posts dynamic is attributing to $_SESSION['custom_page_tile'] = "the title desired". or like in your code

$_SESSION['custom_page_title'] = $eventData['eventtitle'];

also is only possible to atribute a php session a variable if the session is open, please check that. I know the code works, now you just need to check in your dynamic page if you already have the $_SESSION['custom_page_title'] = "your desired dynamic title";

本文标签: shortcodeHow to change page title (from a plugin) in twentytwentyone theme