Как создать пользовательские URL-маршруты?

20 авг. 2011 г., 01:24:08
Просмотры: 123K
Голосов: 70

У меня есть особое требование, и я надеюсь объяснить его не слишком запутанно. Я создал шаблон страницы, где я перечисляю некоторые объекты недвижимости, которые получаю из внешнего XML-файла. Пока никаких проблем, и допустим URL выглядит так:

http://www.example.com/properties/

Каждый объект недвижимости имеет ссылку, которая должна перенаправлять пользователя на страницу "Отдельный объект", отображающую больше информации о нем. Я хотел узнать, есть ли способ сделать ссылку такой:

http://www.example.com/properties/123

Где 123 будет идентификатором объекта недвижимости. То есть, если у меня есть URL вида properties/some_id, я хочу иметь возможность загружать файл представления (как файлы single.php или page.php), но специфичный для этого условия URL.

Это возможно?

0
Все ответы на вопрос 2
10
86

Добавьте это в файл functions.php вашей темы или создайте плагин.

add_action( 'init', 'wpse26388_rewrites_init' );
function wpse26388_rewrites_init(){
    add_rewrite_rule(
        'properties/([0-9]+)/?$',
        'index.php?pagename=properties&property_id=$matches[1]',
        'top' );
}

add_filter( 'query_vars', 'wpse26388_query_vars' );
function wpse26388_query_vars( $query_vars ){
    $query_vars[] = 'property_id';
    return $query_vars;
}

Это добавляет правило перезаписи, которое перенаправляет запросы вида /properties/ с любыми цифрами после на страницу с именем properties, устанавливая переменную запроса property_id. Не забудьте зайти в настройки постоянных ссылок и сохранить их, чтобы обновить правила перезаписи и включить новое правило.

В вашем шаблоне page-properties.php функция get_query_var('property_id') вернёт ID свойства, если он был установлен, в противном случае будет показана стандартная страница свойств.

20 авг. 2011 г. 02:44:23
Комментарии

Это почти сработало для меня, но мне пришлось добавить: add_filter('init','flushRules');
function flushRules(){ global $wp_rewrite; $wp_rewrite->flush_rules(); }

tooshel tooshel
13 нояб. 2012 г. 19:52:34

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

Milo Milo
13 нояб. 2012 г. 22:17:06

Да, я понимаю... но при тестировании очень удобно, когда это есть в коде!

tooshel tooshel
14 нояб. 2012 г. 22:32:02

Более умное регулярное выражение для перезаписи URL может быть таким: ^properties/([0-9]+)/?. Иначе оно будет совпадать с чем-то вроде example/properties/1

Ryan Taylor Ryan Taylor
12 дек. 2014 г. 19:34:52

@RyanTaylor ты уверен в этом? При моих тестах оно не захватывает example/properties/1.

Milo Milo
12 дек. 2014 г. 20:14:15

Где должен находиться файл page-properties.php? Я поместил его в директорию плагина. Это правильно?

Farid Movsumov Farid Movsumov
30 июн. 2016 г. 09:09:56

@FeridMovsumov файлы темы всегда загружаются из директории текущей активной темы, если только вы не добавите фильтр для их загрузки из другого места.

Milo Milo
30 июн. 2016 г. 18:52:36

Привет @Milo, это прекрасный кусок кода. Ты не знаешь, как сделать, чтобы он не конфликтовал при использовании $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ? Функция перехватывает $page (и оставляет его пустым), и я не могу продолжить пагинацию.

Jaypee Jaypee
8 авг. 2017 г. 20:27:05

@Milo что ты имеешь в виду под поместить это в плагин? Где именно? В любое место плагина возможно? Или в wp-content/plugins/myPlugin/myPlugin.php ?

SL5net SL5net
17 мая 2021 г. 14:54:39

Фильтр query_vars не работает (WP 5.7), выдает ошибку: Warning: Invalid argument supplied for foreach() in wp/wp-includes/class-wp.php on line 296

jnaklaas jnaklaas
4 июл. 2021 г. 19:13:44
Показать остальные 5 комментариев
5
11

Другой способ сделать это:

add_action('init', function() {
    add_rewrite_rule( '^properties/([0-9]+)/?',
                      'index.php?pagename=properties&property_id=$matches[1]',
                      'top' );
}, 10, 0);

add_action('init', function() {
    add_rewrite_tag( '%property_id%', '([^&]+)' );
}, 10, 0);

Кодекс Rewrite API/add rewrite rule

Кодекс Rewrite API/add rewrite tag

21 мая 2017 г. 12:24:24
Комментарии

Принятый ответ работает с 4.7 (и 4.8), не уверен, почему вы думаете, что это не так. Ваш код по сути делает то же самое, add_rewrite_tag добавляет переменную запроса в тот же массив, что и фильтр query_vars.

Milo Milo
7 июл. 2017 г. 20:45:11

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

Christian Lescuyer Christian Lescuyer
8 июл. 2017 г. 10:28:30

@Milo Хотя лично я предпочитаю тег rewrite, но все же проверил принятый ответ, и он работает. Просто дело вкуса.

Johansson Johansson
8 июл. 2017 г. 18:36:11

@JackJohansson правила перезаписи (rewrite tags) необходимы, когда вы используете их в структуре постоянных ссылок (permastruct). Это просто дополнительные данные, которые WordPress в данном случае не использует.

Milo Milo
8 июл. 2017 г. 18:47:38

оба правила можно добавить в один и тот же метод, что сделает функцию более чистой и удобной для последующего обслуживания и понимания

eballeste eballeste
14 июл. 2018 г. 18:51:40