Есть ли способ переопределить тег <title>, указанный в header.php?
Во-первых, это не вопрос о SEO и не вопрос о глобальном изменении тега title. Если погуглить мой вопрос, вы увидите только ответы на эти темы.
Итак, у нас есть собственная тема, и мы полностью контролируем header.php. Мы знаем, как установить заголовок. В настоящее время он выглядит так:
<head>
<title><?php wp_title(' | ', true, 'right'); bloginfo('name'); ?></title>
и т.д...
Но проблема в следующем. Для большинства страниц мы хотим, чтобы заголовок отображался как выше. Однако мы поняли, что для одного определенного типа записей (и связанного с ним шаблона) название CPT не должно отображаться публично. Оно только для административного использования. Странно, но так надо. Мы не показываем его ни в H1 шаблона, ни в контенте и т.д.
Но оно отображается в title.
В идеале мы хотели бы иметь возможность переопределить title из header.php прямо в шаблоне, чтобы указать альтернативный заголовок только для этого конкретного набора страниц. Возможно ли это?

Сначала изменим ваш <title>
на
<title><?php wp_title(' | ', true, 'right'); ?></title>
Потому что добавление к строке заголовка таким способом не очень перспективно, вместо этого лучше использовать фильтр для любых изменений заголовка. Поэтому давайте добавим (в functions.php):
add_filter('wp_title', 'my_custom_title');
function my_custom_title( $title )
{
// Возвращаем пользовательский заголовок
return sprintf("%s %s", $title, get_bloginfo('name'));
}
Теперь расширим этот удобный фильтр заголовка, чтобы сделать то, что вам нужно:
add_filter('wp_title', 'my_custom_title');
function my_custom_title( $title )
{
if( is_singular("your_post_type"))
{
return ""; // Возвращаем пустую строку
}
// Возвращаем пользовательский заголовок
return sprintf("%s %s", $title, get_bloginfo('name'));
}

Я опубликовал этот ответ на другой вопрос, но так как он актуален и более современный, подумал, что может быть полезен для некоторых людей.
Способ генерации заголовка документа изменился начиная с WordPress версии 4.4.0. Теперь wp_get_document_title
определяет, как генерируется заголовок:
/**
* Отображает тег title с содержимым.
*
* @ignore
* @since 4.1.0
* @since 4.4.0 Улучшенный вывод заголовка заменил `wp_title()`.
* @access private
*/
function _wp_render_title_tag() {
if ( ! current_theme_supports( 'title-tag' ) ) {
return;
}
echo '<title>' . wp_get_document_title() . '</title>' . "\n";
}
Вот код из версии 5.4.2. Вот фильтры, которые вы можете использовать для управления тегом title:
function wp_get_document_title() {
/**
* Фильтрует заголовок документа перед его генерацией.
*
* Передача непустого значения прервет выполнение wp_get_document_title(),
* возвращая это значение вместо стандартного.
*
* @since 4.4.0
*
* @param string $title Заголовок документа. По умолчанию пустая строка.
*/
$title = apply_filters( 'pre_get_document_title', '' );
if ( ! empty( $title ) ) {
return $title;
}
// --- пропущено ---
/**
* Фильтрует разделитель для заголовка документа.
*
* @since 4.4.0
*
* @param string $sep Разделитель заголовка документа. По умолчанию '-'.
*/
$sep = apply_filters( 'document_title_separator', '-' );
/**
* Фильтрует части заголовка документа.
*
* @since 4.4.0
*
* @param array $title {
* Части заголовка документа.
*
* @type string $title Заголовок просматриваемой страницы.
* @type string $page Опционально. Номер страницы, если есть пагинация.
* @type string $tagline Опционально. Описание сайта на главной странице.
* @type string $site Опционально. Название сайта на других страницах.
* }
*/
$title = apply_filters( 'document_title_parts', $title );
// --- пропущено ---
return $title;
}
Итак, вот два способа, как вы можете это сделать.
Первый использует фильтр pre_get_document_title
, который прерывает генерацию заголовка и, следовательно, более производителен, если вы не собираетесь вносить изменения в текущий заголовок:
function custom_document_title( $title ) {
return 'Вот новый заголовок';
}
add_filter( 'pre_get_document_title', 'custom_document_title', 10 );
Второй способ использует хуки document_title_separator
и document_title_parts
для заголовка и разделителя заголовка, которые выполняются позже в функции, после того как заголовок сгенерирован с использованием функций типа single_term_title
или post_type_archive_title
в зависимости от страницы и готов к выводу:
// Пользовательская функция должна возвращать строку
function custom_seperator( $sep ) {
return '>';
}
add_filter( 'document_title_separator', 'custom_seperator', 10 );
// Пользовательская функция должна возвращать массив
function custom_html_title( $title ) {
return array(
'title' => 'Пользовательский заголовок',
'site' => 'Пользовательский сайт'
);
}
add_filter( 'document_title_parts', 'custom_html_title', 10 );

Объединив различные ответы, вот что сработало для меня в WordPress v5.7.2
и моем пользовательском типе записи company
. Мне удалось легко переопределить заголовок на странице пользовательского типа записи, чтобы добавить название моего сайта в конце
function custom_document_title( $title ) {
if( is_singular("company"))
{
return sprintf("%s - %s", $title, get_bloginfo('name'));
}
return $title; // Возвращаем стандартный заголовок в остальных случаях
}
add_filter( 'pre_get_document_title', 'custom_document_title', 99 );

Предыдущая версия не работала для меня в WordPress 6.1.1, так как возвращала пустой $title. Данная версия возвращает заголовок страницы + название блога или любой произвольный текст, который вы хотите.
function custom_document_title( $title ) {
global $post;
$title = get_the_title($post);
if( is_singular("event")){
return sprintf("%s - %s", $title, 'Регистрация на событие');
} else {
// Возвращаем стандартный заголовок WordPress
return sprintf("%s - %s", $title, get_bloginfo('name'));
}
}
add_filter( 'pre_get_document_title', 'custom_document_title', 99 );
