Как создать пользовательские URL-маршруты?
У меня есть особое требование, и я надеюсь объяснить его не слишком запутанно. Я создал шаблон страницы, где я перечисляю некоторые объекты недвижимости, которые получаю из внешнего XML-файла. Пока никаких проблем, и допустим URL выглядит так:
http://www.example.com/properties/
Каждый объект недвижимости имеет ссылку, которая должна перенаправлять пользователя на страницу "Отдельный объект", отображающую больше информации о нем. Я хотел узнать, есть ли способ сделать ссылку такой:
http://www.example.com/properties/123
Где 123
будет идентификатором объекта недвижимости. То есть, если у меня есть URL вида properties/some_id
, я хочу иметь возможность загружать файл представления (как файлы single.php
или page.php
), но специфичный для этого условия URL.
Это возможно?

Добавьте это в файл 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 свойства, если он был установлен, в противном случае будет показана стандартная страница свойств.

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

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

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

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

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

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

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

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

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

Другой способ сделать это:
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);

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

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

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

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