WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

add_rewrite_rule() WP 2.1.0

Добавляет новое правило перезаписи URL (ЧПУ) в структуру правил WordPress.

Если в правило ЧПУ добавляется новый параметр запроса, то чтобы его можно было получить с помощью get_query_var(), нужно добавить этот новый параметр в белый список с помощью функции add_rewrite_tag(), которая "говорит" WordPress что появились новые параметры запроса. В WP есть белый список параметров запроса, чтобы пользователи не могли добавлять в параметры любые переменные, просто прописав их в УРЛ.

Или можно воспользоваться фильтром 'query_vars':

add_filter( 'query_vars', function( $vars ){
	$vars[] = 'my_var';
	return $vars;
} );

Добавление с помощью 'query_vars' - работает быстрее, т.к. не добавляются теги перезаписи в глобальную $wp_rewrite, как это происходит с add_rewrite_tag().

Функцию нужно вызывать во время или до события init.

Rewrite Rules Inspector — небольшой плагин для просмотра всех имеющихся правил ЧПУ.

Работает на основе: WP_Rewrite::add_rule()
1 раз = 0.000001с = скорость света | 50000 раз = 0.03с = скорость света | PHP 7.1.11, WP 4.9.8

Хуков нет.

Возвращает

Ничего не возвращает.

Использование

add_rewrite_rule( $regex, $query, $after );
$regex(строка) (обязательный)
Регулярное выражение, которому должна соответствовать ссылка (УРЛ). В регулярке можно использовать одну или несколько групп (()).
По умолчанию: нет
$query(строка/array) (обязательный)
Соответствующие регулярке параметры запроса. Можно использовать массив $matches[], чтобы получить значения групп регулярки.
С версии 4.4. поддерживает массив.
По умолчанию: нет
$after(строка)
Приоритет проверки. Может быть top и bottom. top - значит это правило будет проверяться первым.
По умолчанию: 'bottom'

Примеры

#1. ЧПУ для страниц

Мы создаем страницу "питание" (nutrition, ID=12) для отображения на ней различной информации о питании. Далее, эта страница использует отдельный шаблон. На страницу передаются переменные запроса food и variety.

Сделаем вместо некрасивых УРЛ: /nutrition?food=kasha&variety=manka, красивые: /nutrition/kasha/manka.

add_action('init', 'do_rewrite');
function do_rewrite(){
	// Правило перезаписи
	add_rewrite_rule( '^(nutrition)/([^/]*)/([^/]*)/?', 'index.php?pagename=$matches[1]&food=$matches[2]&variety=$matches[3]', 'top' ); 
	// нужно указать ?p=123 если такое правило создается для записи 123
	// первый параметр для записей: p или name, для страниц: page_id или pagename

	// скажем WP, что есть новые параметры запроса
	add_filter( 'query_vars', function( $vars ){
		$vars[] = 'food';
		$vars[] = 'variety';
		return $vars;
	} );
}

При использовании $matches[], ключи массива начинаются с 1, а не 0. Как и положено в регулярных выражениях.

Теперь нужно обновить правила перезаписи, для этого зайдите в настройки ЧПУ и просто обновите настройки - правила обновятся в опциях ВП.

Получить параметры в коде страницы можно через функцию get_query_var(). Например, ссылка: /nutrition/sup/risoviy

echo get_query_var('food'); // > sup
echo get_query_var('variety'); // > risoviy

По умолчанию WordPress не распознает новые переменные запроса, используемые для перезаписи. Для этого нужно их зарегистрировать при помощи функции add_rewrite_tag() или через фильтр query_vars, если этого не сделать, правило перезаписи работать не будет.

Чтобы правило начало работать, нужно обновить (сбросить) правила в БД. Для этого нужно вызвать функцию flush_rules(). Или просто зайти в Настройки -> Постоянные ссылки там автоматически сработает flush_rules().

#2. ЧПУ для страницы (пример 2)

Еще один пример создания ЧПУ для постоянной страницы. Сначала код:

## Правило перезаписи для страницы sitemap
add_action( 'init', 'rewrite_rule_my' );
function rewrite_rule_my(){
	add_rewrite_rule( '^(sitemap)/([^/]*)/?', 'index.php?pagename=$matches[1]&pagetype=$matches[2]', 'top' );
	add_rewrite_tag( '%pagetype%', '([^&]+)' );
}

Тут мы создавали ЧПУ для постоянной страницы /sitemap?pagename=value (pagename - переменная запроса). После размещения этого кода в functions.php, начнет работать ЧПУ вида: /sitemap/value и в PHP на этой странице, можно будет использовать переменную $wp_query->query_vars['pagetype'], которая будет содержать в себе значение value. Или значение можно получить так: get_query_var('pagetype').

#3. ЧПУ для дочерней страницы

В параметр pagename нужно передать всю связь, а не только ярлык (slug) страницы. Допустим УРЛ нашей дочерней страницы: /parent/slug, тогда:

add_rewrite_rule( '^(parent/slug)/([^/]*)', 'index.php?pagename=$matches[1]&foo=$matches[2]', 'top' );

Т.е. в регулярном выражении нужно писать (parent/slug) а не parent/(slug)

Теперь WP начнет понимать УРЛ вида /parent/slug/value, где value будет доступна через get_query_var('foo');.

#4. Дружелюбная ссылка входа

Это просто пример, не имеющий никакой практической пользы. C версии 3.0 WordPress автоматически перенаправляет на /wp-login.php, если мы пытаемся зайти на /login, но так было не всегда.

Пример того, как можно сделать ссылку на страницу входа более дружелюбной, т.е. сделать так, что если мы напишем в строку браузера http://example.com/login нас перекинет на страницу входа http://example.com/wp-login.php:

## редирект с /login на /wp-login.php
add_action( 'init', 'wp_pretty_login' );
function wp_pretty_login() {
	add_rewrite_rule( 'login$', 'wp-login.php', 'top' );
}

Заметки

  • Global. WP_Rewrite. $wp_rewrite WordPress rewrite component.

Список изменений

С версии 2.1.0 Введена.
С версии 4.4.0 Array support was added to the $query parameter.

Код add_rewrite_rule() WP 5.5.1

wp-includes/rewrite.php
<?php
function add_rewrite_rule( $regex, $query, $after = 'bottom' ) {
	global $wp_rewrite;

	$wp_rewrite->add_rule( $regex, $query, $after );
}

Cвязанные функции

Из метки: Rewrite (ЧПУ перезапись)

14 комментов
Полезные 2 Вопросы 4 Все