Пользовательские конечные точки (endpoints) для постоянных ссылок произвольного типа записей

14 февр. 2012 г., 15:42:56
Просмотры: 16.2K
Голосов: 8

У меня есть произвольный тип записей "destinations", и я установил маску EP для этого типа записей на EP_PERMALINK по умолчанию. Я добавил несколько конечных точек следующим образом:

add_filter( 'query_vars', 'add_query_vars');

function add_query_vars($vars){
    $vars[] = "tours";     // Добавляем переменную tours
    $vars[] = "activities"; // Добавляем переменную activities
    return $vars;
}

add_action('init', 'add_endpoints');

function add_endpoints(){
    global $wp_rewrite; 

    // Регистрируем конечные точки
    add_rewrite_endpoint('tours', EP_PERMALINK);
    add_rewrite_endpoint('activities', EP_PERMALINK);

    // Сбрасываем правила перезаписи
    $wp_rewrite->flush_rules();
}

Когда я тестирую это на обычной записи, происходит перенаправление на нужный мне шаблон (у меня есть обработчик перенаправления шаблонов для хука single template):

Например: somesite.com/test-category/test/activities/

Но для произвольного типа записей (который является иерархическим) конечная точка просто удаляется из URL, и остается шаблон single-destination.php

Например: somesite.com/destination/south-africa/kruger-national-park/activities/

превращается в

somesite.com/destination/south-africa/kruger-national-park/

Любая помощь или подсказка будет очень ценной. Я мучаюсь с этим уже несколько часов безрезультатно :(

Спасибо

0
Все ответы на вопрос 1
6
27

Несколько моментов. Во-первых, названия ваших функций должны иметь уникальный префикс. WordPress — это большая экосистема, и кто-то уже наверняка использовал все общие названия функций, которые вы можете придумать.

Во-вторых, add_rewrite_endpoint автоматически добавляет переменные запроса, поэтому вам не нужно это:

add_filter( 'query_vars', 'add_query_vars');
function add_query_vars($vars){
    $vars[] = "tours";
    $vars[] = "activities";
    return $vars;
}

Сброс правил перезаписи при каждой загрузке — плохая идея. Это нужно делать только один раз после добавления новых правил, например, при активации плагина. Поэтому вашу функцию add_endpoints можно сократить до такого вида (с более подходящим названием, как упоминалось выше):

<?php
add_action('init', 'wpse42279_add_endpoints');
function wpse42279_add_endpoints()
{
    add_rewrite_endpoint('tours', EP_PERMALINK);
    add_rewrite_endpoint('activities', EP_PERMALINK);
}

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

<?php
add_action('init', 'wpse42279_add_endpoints');
function wpse42279_add_endpoints()
{
    add_rewrite_endpoint('tours', EP_PAGES);
    add_rewrite_endpoint('activities', EP_PAGES);
}

Но даже так это не будет работать так, как вы ожидаете. Конечные точки устанавливают переменную запроса равной тому, что идет после них. Например, если ваш URL выглядит так:

yoursite.com/some-country/some-city/activities/asdf

то переменная запроса activities будет равна "asdf". Если после activities ничего нет, переменная запроса будет пустой (но установленной), поэтому она всегда будет оцениваться как false при попытке её перехватить:

<?php
add_action( 'template_redirect', 'wpse42279_catch_vars' );
function wpse42279_catch_vars()
{
    if( get_query_var( 'tours' ) )
    {
        // выполняем действия!
        exit();
    }
}

Это можно обойти, фильтруя request и изменяя значение переменных tours и activities на true, если они установлены.

<?php
add_filter( 'request', 'wpse42279_filter_request' );
function wpse42279_filter_request( $vars )
{
    if( isset( $vars['tours'] ) ) $vars['tours'] = true;
    if( isset( $vars['activities'] ) ) $vars['activities'] = true;
    return $vars;
}

Рекомендую ознакомиться с руководством по Rewrite API, которое я написал. Однако, основные моменты, касающиеся вашего вопроса, изложены выше.

14 февр. 2012 г. 16:56:29
Комментарии

Спасибо за потрясающий ответ! Я внес изменения согласно вашему посту и руководству. Но, похоже, WordPress перенаправляет/удаляет конечную точку и любые переменные после нее при загрузке URL. Не уверен, это каноническое перенаправление или что-то еще. Но он удаляет только зарегистрированные конечные точки. Если я добавлю что-то случайное в конец URL, то получу 404. Но "tours" или "activities" удаляются или перенаправляют на URL отдельного направления. :(

Charl Pretorius Charl Pretorius
15 февр. 2012 г. 10:35:42

Кажется, я нашел проблему. Она связана с настройками постоянных ссылок. У меня было пользовательское значение - /%category%/%postname%/. Но если я установлю просто /%postname%/, то все работает, пока не понимаю почему, но разберусь. Спасибо \0/

Charl Pretorius Charl Pretorius
15 февр. 2012 г. 11:27:41

Попробуй вернуть обратно /%category%/%postname%/ - теперь это может снова заработать. Подозреваю, что причина, по которой WP удалял ваши данные, заключалась в необходимости сбросить правила перезаписи. (Возможно.)

chrisguitarguy chrisguitarguy
15 февр. 2012 г. 16:49:30

У меня тоже были пользовательские настройки постоянных ссылок. Я просто зашел в Настройки постоянных ссылок и нажал Сохранить изменения, ничего не меняя, после этого конечная точка заработала.

yitwail yitwail
11 февр. 2013 г. 10:29:29

Это мне очень помогло! Большое спасибо, брат!

fdrv fdrv
23 июл. 2018 г. 21:48:59

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

fdrv fdrv
23 июл. 2018 г. 21:51:57
Показать остальные 1 комментариев