add_rewrite_rule()
Додає нове правило перезапису URL (ЧПУ) до структури правил WordPress.
Якщо в правило ЧПУ додається новий параметр запиту, то щоб його можна було отримати за допомогою get_query_var() , потрібно додати цей новий параметр у білий список за допомогою функції add_rewrite_tag() , яка “каже” WordPress, що з’явилися нові параметри запиту. У WP є білий список параметрів запиту, щоб користувачі не могли додавати до параметрів будь-які змінні, просто прописавши їх в УРЛ.
Або можна скористатися фільтром query_vars
. На відміну від add_rewrite_tag() , у цьому випадку не додаються теги перезапису в глобальний об’єкт $wp_rewrite :
add_filter( 'query_vars', function( $vars ){ $vars[] = 'my_var'; return $vars; } );
Функцію потрібно викликати під час або до події init .
При додаванні кількох правил зверніть увагу, що (починаючи з версії 4.9.8) правила застосовуються в порядку додавання, незалежно від того, чи вони вгорі чи внизу. Наприклад:
add_rewrite_rule( '^book/(.*)', 'index.php?pagename=foo&book=matches[1]', 'top' ); add_rewrite_rule( '^book/mammals/(.*)', 'index.php?pagename=foo&bookmam=matches[1]', 'top' );
Друге правило ніколи не спрацює, тому що завжди спрацьовуватиме перше правило до обробки другого.
Дивіться список зайнятих назв для змінних запитів.
Rewrite Rules Inspector – невеликий плагін для перегляду всіх правил ЧПУ.
WP_Rewrite::add_rule()
(швидкість світла) | 50000 разів – 0.03 сек
(швидкість світла) |
PHP 7.1.11, WP 4.9.8
Хуків немає.
Повертає
null
. Нічого не вертає.
Використання
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 Перенаправлення на файл, відмінний від index.php
Використання правил перезапису для перенаправлення на скрипти, які відрізняються від index.php.
Аргумент $redirect
працює інакше при перенаправленні на НЕ index.php
PHP-скрипт. У цьому випадку WordPress передає ці перенаправлення .htaccess
замість того, щоб обробляти їх самостійно.
Тому змінні слід записувати як $1
замість $matches[1]
.
add_action( 'init', 'custom_rewrite_rule', 10, 0); function custom_rewrite_rule() { add_rewrite_rule( 'nutrition/([^/]*)/([^/]*)/?', 'path/to/script.php?food=&variety=', 'top' ); }
При додаванні такого правила — див. WP_Rewrite::add_external_rule() .
Він додає правило перезапису до окремого масиву non_wp_rules
: див. WP_Rewrite::$non_wp_rules . Надалі дані з цього масиву потраплятимуть безпосередньо до .htaccess
.
Тобто після встановлення наведеного вище коду та оновлення правил перезапису у вас з’явиться нове правило (рядок 7) в .htaccess
:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index.php$ - [L] RewriteRule ^nutrition/([^/]*)/([^/]*)/? /path/to/script.php?food=&variety= [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule. /index.php [L] </IfModule> # END WordPress
Дружнє посилання для входу в систему
Це просто приклад, який не має практичного застосування. WordPress з версії 3.0 автоматично перенаправляє на /wp-login.php
, якщо ми намагаємося перейти на /login
.
// Let's make http://site.com/login count request for http://site.com/wp-login.php add_action('init', 'wp_pretty_login'); function wp_pretty_login() { add_rewrite_rule( 'login$', 'wp-login.php', 'top' ); }
Після встановлення цього коду, якщо ми введемо http://example.com/login
в рядок браузера, відкриється сторінка входу http://example.com/wp-login.php
(URL не зміниться – перенаправлення не буде):
У .htaccess отримаємо таке:
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index.php$ - [L] RewriteRule ^login$ /wp-login.php [QSA,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule. /index.php [L] </IfModule> # END WordPress
нотатки
- Global. WP_Rewrite. $wp_rewrite WordPress rewrite component.
список змін
З версії 2.1.0 | Введено. |
З версії 4.4.0 | Array support був added to $query parameter. |
Код add_rewrite_rule() add rewrite rule WP 6.0.2
function add_rewrite_rule( $regex, $query, $after = 'bottom' ) { global $wp_rewrite; $wp_rewrite->add_rule( $regex, $query, $after ); }