Как эмулировать поведение постоянных ссылок на статических страницах
Я работаю над сайтом на WordPress, который отображает результаты из API событий на определенной странице.
Страница находится по адресу /whats-on.
Я хочу разместить на странице ссылки вида mysite.com/whats-on/название-события, которые будут вести на другую страницу с деталями события. Если я просто добавлю такие ссылки, WordPress попытается найти запись с названием 'название-события' и выдаст 404 ошибку.
Есть ли способ обойти это поведение? Как я могу добавить перезапись URL через плагин?
ОБНОВЛЁННЫЙ КОД:
class SpektrixPlugin {
public function activate() {
global $wp_rewrite;
flush_rewrite_rules();
add_action('init',array($this, 'properties_add_rewrite_rules'));
add_filter('query_vars', array($this, 'properties_add_query_vars'));
}
public function properties_add_query_vars( $vars) {
$vars[] = "event"; // название переменной, как она будет отображаться в URL
return $vars;
}
public function properties_add_rewrite_rules() {
// Замените your_page_id на ID вашей страницы whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?p=8&event='.$matches[1] , 'top' );
}
public function spektrix_list_events() {
$api = new SpektrixApiClient();
return $api->getAllEvents();
}
}
$SpektrixEvents= new SpektrixPlugin();
register_activation_hook( __file__, array($SpektrixEvents, 'activate') );

Вам необходимо добавить правила перезаписи и query_vars в соответствии с вашими потребностями.
Например. В вашем файле functions.php или плагина:
// Регистрируем новые переменные для использования в правилах перезаписи
add_filter('query_vars', 'properties_add_query_vars');
function properties_add_query_vars( $vars) {
$vars[] = "my_action"; // имя переменной, как оно будет выглядеть в URL
return $vars;
}
// Добавляем новое правило перезаписи к существующим
add_action('init','properties_add_rewrite_rules');
function properties_add_rewrite_rules() {
//Замените your_page_id на ID страницы whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=your_page_id&my_action='.$matches[1] , 'top' );
}
Затем в шаблоне для страницы whats-on (создайте файл шаблона page-whats-on.php, см. это):
global $wp_query;
if(isset($wp_query->query_vars('my_action')) && $wp_query->query_vars('my_action') == 'some_action'){
//Делаем что нужно
}
Не забудьте сбросить правила перезаписи перед тестированием новых правил. Это можно сделать, перейдя в Настройки→Постоянные ссылки и нажав кнопку Сохранить.
РЕДАКТИРОВАНИЕ
В вашем обновленном вопросе есть несколько проблем в коде.
- В моем коде была ошибка, где переменная запроса для страницы указана как
page_id
, а я написал простоp
. Извините за это. - Правила перезаписи и пользовательские query_vars должны добавляться на хуке init, только flush_rewrite_rules(); должен выполняться только на хуке активации из-за соображений производительности (я сам задавал связанный вопрос).
Я протестировал этот код, и он работает:
class SpektrixPlugin {
public function __construct(){
add_filter('query_vars', array($this, 'add_query_vars'));
add_action('init', array($this, 'add_rewrite_rules'));
}
public function activate() {
flush_rewrite_rules();
}
public function deactivate() {
flush_rewrite_rules();
}
public function add_query_vars($vars) {
$vars[] = "event"; // имя переменной, как оно будет выглядеть в URL
return $vars;
}
public function add_rewrite_rules() {
//Замените your_page_id на ID страницы whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=8&event=$matches[1]' , 'top' );
}
public function spektrix_list_events() {
//$api = new SpektrixApiClient();
//return $api->getAllEvents();
return 'Test';
}
}
$SpektrixEvents = new SpektrixPlugin();
register_activation_hook( __file__, array($SpektrixEvents, 'activate') );
register_deactivation_hook( __file__, array($SpektrixEvents, 'deactivate') );
Теперь вам нужно проверить, когда присутствует query var event
. В вашем случае, как я уже говорил, лучший способ сделать эту проверку - в шаблоне страницы. Вы можете создать конкретный шаблон для вашей страницы с ID 8. Просто создайте файл page-8.php и поместите его в папку вашей темы (вы также можете поместить его в папку плагина, но это требует дополнительной работы). В page-8.php вы можете сделать что-то вроде этого:
<?php
get_header();
global $wp_query;
if($wp_query->get('event') == 'event'){
echo $SpektrixEvents->spektrix_list_events();
}
get_footer();
?>
Теперь, если вы перейдете на yoursite.com/whats-on/event/, вы увидите вывод "Test".

Спасибо. Предполагается ли, что приведённый выше код должен быть в functions.php темы? Как мне реализовать это в плагине? Я также не совсем понимаю, зачем здесь wp_query? Ведь я не делаю запрос к базе данных.

Первый фрагмент кода должен быть в functions.php или в файле плагина. Второй фрагмент желательно разместить в шаблоне конкретной страницы для вашей страницы /whats-on. Я использовал $wp_query для проверки, установлена ли пользовательская query переменная и получения её значения, а не для запроса к базе данных. После проверки вы можете выполнять запросы напрямую к базе данных или делать что-то ещё. Обратите внимание, что эти рекомендации даны потому, что вы просили переписать код именно для страницы /whats-on.

Я обновил вопрос, добавив код. Но при переходе на mysite.com/whats-on/name-of-the-event всё равно получаю 404 ошибку. Можете заметить, что я сделал не так? Уже много часов бьюсь над этим :-/. Правила перезаписи URL я сбросил.

Еще раз спасибо. Я продвинулся немного дальше. Однако, эти сбросы перезаписи, похоже, не работают, и мне приходится вручную нажимать "Сохранить" в настройках постоянных ссылок.

Да, я только что заметил это, но после того, как настройки постоянных ссылок были вручную сброшены, это работает, так?
