Изменение the_title() страницы динамически

28 янв. 2013 г., 23:39:36
Просмотры: 21K
Голосов: 11

Я разрабатываю плагин, который не использует пользовательский тип записи, а использует отдельные таблицы базы данных. Это плагин, который отображает список курсов со ссылками, ведущими на различные страницы с подробностями о курсах, где пользователь затем может подписаться на курс.

В текущем состоянии я использую шорткод для получения данных плагина на странице с пользовательским шаблоном страницы (page-courses.php).

Теперь я хочу динамически изменять the_title() в соответствии со страницей, которую показывает плагин (список курсов, страница с подробностями курса и формами, страница успешной отправки формы). Но когда я делаю это с помощью следующего фильтра, ссылки на другие страницы в футере также изменяются:

<?php
 
add_filter('the_title', 'custom_page_title');
function custom_page_title() {
    return 'Пользовательский заголовок';
}

Редактирование

В footer.php у меня есть функция, которая включает ссылки футера с помощью wp_nav_menu(), чтобы я мог определить их в Внешний вид > Меню. Но с вышеуказанным фильтром все ссылки в футере также меняются на 'Пользовательский заголовок'. Но я просто хочу изменить заголовок страницы, не затрагивая ссылки меню в футере.

Пытаясь добавить условный тег 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 'Пользовательский заголовок';
}

Это похоже на этот вопрос: проблема фильтра the_title в навигации, только в том, что затронутые ссылки находятся в футере и in_the_loop() не работает.

Как я могу изменить the_title(), влияя только на заголовок текущей отображаемой страницы, не затрагивая ссылки в футере?

Редактирование 2 - Решение

Итак, наконец я заставил это работать:

<?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 'Пользовательский заголовок';
    }
    return $title;
}

Файл page-listcourses.php - это пользовательский шаблон страницы, который я назначил статической странице с названием 'Курсы'.

Я предполагаю, что раньше это не работало, потому что название статической страницы и имя файла пользовательского шаблона страницы были одинаковыми.

5
Комментарии

Почему вы создаете собственные таблицы в базе данных? Ваша жизнь была бы намного проще, если бы вы реализовали ваш пользовательский контент как Произвольный тип записи (Custom Post Type).

Chip Bennett Chip Bennett
29 янв. 2013 г. 17:10:30

Я как раз думал, что этот вопрос возникнет. Я разрабатываю этот плагин, чтобы изучить WordPress, поэтому изначально не знал о Произвольных типах записей. У меня есть две таблицы в базе данных: одна для курсов, а другая для категорий курсов. Одна категория может содержать несколько курсов, поэтому таблицы связаны между собой. Я не думаю, что это так просто реализовать с помощью Произвольных типов записей. Конечно, я мог бы использовать Произвольные таксономии (Custom Taxonomies) для курсов, но мне пришлось бы добавлять дополнительные поля, потому что категория курса - это не просто название. Пока что гораздо проще сделать это с помощью пользовательских таблиц базы данных.

Gchtr Gchtr
29 янв. 2013 г. 21:23:21

Ваш случай использования - это именно тот сценарий, для которого предназначены Произвольные типы записей и Произвольные таксономии. Возможно, вы недооцениваете элегантность, гибкость и мощь CPT и Произвольных таксономий.

Chip Bennett Chip Bennett
29 янв. 2013 г. 21:25:52

Действительно, возможно, что я так и сделаю. Наверное, мне просто стоит попробовать. Спасибо за совет.

Gchtr Gchtr
29 янв. 2013 г. 21:30:09

in_the_loop() устанавливается в true при каждом вызове the_post(). Не углубляясь слишком сильно в ядро WordPress и учитывая, что навигационные меню сами по себе являются циклами, я предполагаю, что где-то в процессе wp_nav_menu() инициирует цикл, из-за чего in_the_loop() возвращает true.

Chip Bennett Chip Bennett
30 янв. 2013 г. 16:22:06
Все ответы на вопрос 4
9

Я бы использовал условную функцию is_page_template():

if ( is_page_template( 'page-courses.php' ) ) {
    // Текущая страница использует ваш
    // пользовательский шаблон страницы;
    // выполните какие-либо действия
}

Редактирование

Эту условную функцию следует использовать внутри вашего callback-фильтра:

function wpse83525_filter_the_title( $title ) {
    if ( is_page_template( 'page-courses.php' ) ) {
        return 'Пользовательский заголовок';
    }
    return $title;
}
add_filter( 'the_title', 'wpse83525_filter_the_title' );

Теперь, чтобы изолировать только заголовки страниц, использующих ваш шаблон, можно воспользоваться вторым параметром, передаваемым в the_title: $id. Поскольку вам известен ID записи, для которой фильтруется заголовок, можно запросить метаданные _wp_page_template и убедиться, что они соответствуют вашему шаблону:

function wpse83525_filter_the_title( $title, $id ) {
    if ( 'page-courses.php' == get_post_meta( $id, '_wp_page_template', true ) ) {
        return 'Пользовательский заголовок';
    }
    return $title;
}
add_filter( 'the_title', 'wpse83525_filter_the_title', 10, 2 );

Редактирование 2

Если вы хотите нацелиться конкретно на страницу "Курсы", используйте is_page() с указанием slug страницы 'courses' или её заголовка 'Courses':

function wpse83525_filter_the_title( $title ) {
    if ( is_page( 'Courses' ) ) {
        return 'Пользовательский заголовок';
    }
    return $title;
}
add_filter( 'the_title', 'wpse83525_filter_the_title' );

Тем не менее, я бы рекомендовал преобразовать page-courses.php в Пользовательский шаблон страницы, что сделает весь процесс более надёжным.

29 янв. 2013 г. 17:09:43
Комментарии

Пока это не сработало. Но я уточнил свой вопрос, потому что, возможно, он был недостаточно конкретным. Может быть, проблема в чем-то другом.

Gchtr Gchtr
30 янв. 2013 г. 15:46:35

Что вы имеете в виду под "пока это не сработало"? Что именно вы пробовали? Что должно было произойти, но не произошло, или что случилось неожиданно?

Chip Bennett Chip Bennett
30 янв. 2013 г. 16:05:09

Смотрите обновленный ответ, он должен решить проблему с заголовками пунктов навигационного меню.

Chip Bennett Chip Bennett
30 янв. 2013 г. 16:31:43

Я сказал это, потому что думаю, что ваш ответ может быть правильным (направляет в верную сторону), но, возможно, я недостаточно четко сформулировал свой вопрос. get_post_meta( $id, '_wp_page_template', true ) возвращает default, и я не знаю, что с этим делать. Когда я устанавливаю 'page-courses.php' в качестве 'default', все ссылки в навигации изменяются, кроме случаев, когда я подключаю фильтр the_title к loop_start — тогда изменяются только ссылки в подвале. Я проверил, какой файл шаблона используется, и это 'page-courses.php', а не 'page.php' (который, как я думал, может быть шаблоном по умолчанию).

Gchtr Gchtr
30 янв. 2013 г. 17:46:42

Значит, "Courses" — это название вашей статической страницы?

Chip Bennett Chip Bennett
30 янв. 2013 г. 18:24:30

Да, это название статической страницы.

Gchtr Gchtr
30 янв. 2013 г. 18:37:57

Смотрите обновленный ответ. Можно выбрать страницу по её заголовку или слагу, используя is_page().

Chip Bennett Chip Bennett
30 янв. 2013 г. 18:51:07

Теперь всё работает. Смотрите первый вопрос в посте, чтобы увидеть, что я сделал. Файл page-courses.php всегда был Кастомным Шаблоном Страницы. Полагаю, что раньше это не работало, потому что имя статической страницы и имя файла Кастомного Шаблона Записи совпадали. Спасибо за ваши усилия!

Gchtr Gchtr
30 янв. 2013 г. 19:11:27

Для будущих случаев: я рекомендую не называть кастомные шаблоны страниц как page-foobar.php, именно по этой причине. Вместо этого я использую template-foobar.php.

Chip Bennett Chip Bennett
30 янв. 2013 г. 19:16:58
Показать остальные 4 комментариев
3

Хотя is_page_template() будет работать, я предпочитаю размещать подобный код непосредственно в шаблоне страницы, чтобы весь код, генерирующий этот тип страницы, находился в одном файле.

29 янв. 2013 г. 18:58:58
Комментарии

Как это будет работать, если предположить, что код использует the_title()? Примеры кода?

Chip Bennett Chip Bennett
29 янв. 2013 г. 19:54:19

@ChipBennett, я не понимаю вопрос. Если ему нужно, чтобы фильтр применялся только для страницы с определённым шаблоном, тогда он может разместить тот же код в шаблоне перед вызовом get_header().

Mark Kaplun Mark Kaplun
29 янв. 2013 г. 21:25:09

Да, на самом деле я тоже думаю, что это сработает. Однако, мне кажется, мне придётся сделать обходной путь, чтобы установить переменную в плагине, которая будет доступна в query_vars? Поэтому для меня фильтрация the_title — более красивое решение.

Gchtr Gchtr
30 янв. 2013 г. 19:19:45
0

Если вам нужно изменить только заголовок текущей страницы, используйте условную проверку in_the_loop(), как показано ниже:

add_filter( 'the_title', 'modify_onpage_title', 10, 2);

function modity_onpage_title( $title , $id = null ) {

    if(!in_the_loop()){
        // Прерываем выполнение, если проверка не прошла (например, в циклах меню)
        return $title;
    }

    // Модифицируем заголовок
    $title = "Йоу! ". $title;
    return $title;
}
8 нояб. 2016 г. 14:08:32
0

Попробуйте использовать условные теги, чтобы гарантировать, что функция the_title() изменяется только на нужных вам страницах.

29 янв. 2013 г. 16:50:06