Вопрос или проблема
Я пытаюсь (и не удается) использовать правила переписывания, чтобы перенаправить более короткие/красивые URL на нужную страницу И включить значения в строку запроса.
WP установлен на https://example.com, и плагин создает страницу под названием ‘foo’, которая использует значение ‘bar’, переданное в строке запроса, для генерации контента из пользовательских таблиц базы данных.
Таким образом, пример полного URL будет следующим:
https://example.com/foo/?bar=XXXXXX
Значение ‘bar’ всегда будет строкой длиной от 6 до 8 буквенно-цифровых символов с минимум 1 дефисом (-).
Я хочу использовать правила переписывания (но открыт к другим предложениям), чтобы можно было использовать более короткий URL, например:
Я пробовал использовать add_rewrite_rule следующим образом:
function jr_rewrite_add_rewrites(){
add_rewrite_rule(
'f\/([[:ascii:]]+)\/?$',
'/index.php?pagename=foo&bar=$matches[1]',
'top'
);
}
add_action( 'init', 'jr_rewrite_add_rewrites');
И когда я сбрасываю правила переписывания, нажимая “Сохранить” на странице настроек постоянных ссылок в панели управления, правило добавляется в файл htaccess без проблем:
# BEGIN WordPress
# Директивы (строки) между `BEGIN WordPress` и `END WordPress` являются
# динамически сгенерированными и должны изменяться только с помощью фильтров WordPress.
# Любые изменения в директивах между этими маркерами будут перезаписаны.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^f\/([[:ascii:]]+)\/?$ /index.php?pagename=foo&bar=$matches[1] [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Однако, когда я пытаюсь получить доступ к:
страница просто перенаправляется на:
и не содержит нужной bar=XXXXXX строки запроса, поэтому соответствующий контент не загружается.
Кто-нибудь может указать, где я ошибаюсь в этом, или предложить альтернативу?
В этом ответе два момента:
- С вашим текущим примером происходит множество ошибок, и некоторые из них вызваны правилами WordPress, усложняющими ситуацию. Если вы не против редактировать свой файл .htaccess напрямую, попробуйте это. Это избавит от необходимости иметь дело с некоторой магией WordPress, которая не упрощает ситуацию. Это должно сделать то, что вы хотите, или быть достаточно близким, чтобы вы могли настроить это под свои нужды:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^f/(.{6-8})$ foo/?bar=$1 [NC,L]
</IfModule>
Вам нужно будет удалить код вашего плагина, удалить строку, которая находится в .htaccess (хотя, я полагаю, это должно происходить автоматически), и добавить это выше секции WordPress.
Обратите внимание, это не перенаправление. URL в браузере не изменится, но URL, который PHP видит “за кулисами”, будет переписанным.
- Если вы все еще хотите попробовать исправить это, используя
add_rewrite_rule()
, есть несколько моментов, которые нужно исправить. Вот обновленная попытка, хотя я не могу легко это протестировать:
add_rewrite_rule(
'^f/(.{6-8})$',
'index.php?pagename=foo&bar=$matches[1]',
'top'
);
- Не экранируйте /
- Удалите ведущий / в index.php (возможно, поэтому он добавился как правило в .htaccess вместо работы в самом WordPress, как это должно быть)
- Удалите ненужные /?
- Сделайте это конкретно 6-8 символов в соответствии с вашим постом
- Упростите сопоставленный символ до
.
(любой символ). Вы можете сделать это, например, [a-zA-Z0-9], если хотите ограничить только этими символами, так как это явно и ясно
Еще один момент — вы на 100% уверены, что pagename=foo
является правильным способом попасть по этому URL. Я не уверен, как работает index.php, поэтому вам нужно это проверить.
В дополнение к тому, что полезно предложил mozboz выше, мне удалось использовать функциональность переписывания WordPress, чтобы сделать работу с помощью add_rewrite_tag()
, чтобы распознать переменную bar, а также get_query_var()
, чтобы получить доступ к значению вместо того, чтобы пытаться получить доступ к $_GET['bar']
.
Итак, код, с которым я в итоге остался, был следующим:
function foobar_rewrite_rules(){
add_rewrite_tag(
'%bar%',
'(.{6})'
);
add_rewrite_rule(
'^f/(.{6-8})$',
'index.php?pagename=foo&bar=$matches[1]',
'top'
);
}
add_action( 'init', 'foobar_rewrite_rules');
А затем, поскольку страница должна была работать независимо от того, использовался ли ‘красивый’ URL или ‘уродливый’ с полным адресом страницы и не измененными строками запроса, мне просто нужно было проверить и выбрать между версией $_GET и версией get_query_var() следующим образом:
$bar_value = (empty($_GET['bar'])) ? (get_query_var('bar', FALSE)) : ($_GET['bar']) ;
Мне очень приятно, что это заработало, спасибо за помощь!
Ответ или решение
Для решения вашей проблемы с настройкой пользовательских правил перезаписи (rewrite rules) в WordPress, чтобы сократить URL и корректно передать значения в строке запроса, мы исследуем несколько аспектов, подходящих для вашей ситуации.
Проблема и контекст
Вы установили WordPress на https://example.com и имеете страницу под названием «foo», которая генерирует контент на основе значений из строки запроса. Вы хотите, чтобы URL, содержащие параметр «bar», выглядели более привлекательно, например, https://example.com/f/XXXXXX, вместо https://example.com/foo/?bar=XXXXXX.
Ход решения
Для достижения этой цели, использование функции add_rewrite_rule()
в WordPress — правильный подход, однако, существуют нюансы, которые важно учесть.
1. Правильная настройка правил
Ваш код для добавления правила перезаписи ничем не плох, но давайте немного оптимизируем его:
function foobar_rewrite_rules() {
add_rewrite_tag('%bar%', '([a-zA-Z0-9\-]{6,8})');
add_rewrite_rule(
'^f/([a-zA-Z0-9\-]{6,8})/?$',
'index.php?pagename=foo&bar=$matches[1]',
'top'
);
}
add_action('init', 'foobar_rewrite_rules');
Обратите внимание на следующие изменения:
- Используйте
add_rewrite_tag()
, чтобы зарегистрировать тег%bar%
, который можно будет использовать в функцииget_query_var()
. - Убедитесь, что регулярное выражение
[a-zA-Z0-9\-]{6,8}
соответствует вашему требованию о том, что строка будет длиной от 6 до 8 символов и содержать хотя бы одну дефис. - Убедитесь, что не добавляете лишние символы, такие как
&
. Используйте&
для правильной работы URL.
2. Сброс правил перезаписи
После внесения изменений в код, не забудьте сбросить правила перезаписи. Это можно сделать, зайдя в настройки «Постоянные ссылки» в админ-панели WordPress и просто нажав «Сохранить изменения», даже если ничего не меняется.
3. Получение значения из строки запроса
Теперь, когда URL работает, вам нужно корректно извлекать значение bar
в вашем коде. Вместо прямого доступа к $_GET['bar']
, рекомендуется использовать get_query_var()
:
$bar_value = get_query_var('bar', false);
if ($bar_value === false) {
$bar_value = isset($_GET['bar']) ? $_GET['bar'] : '';
}
Заключение
С применением указанных изменений, вы сможете успешно перенаправлять более короткие URL, такие как https://example.com/f/XXXXXX, на страницу «foo» и передавать нужное значение в строке запроса. Убедитесь, что все изменения корректно проверены и протестированы, чтобы обеспечить успешную работу сайта.
Помните, что корректная работа URL — это не только улучшение пользовательского опыта, но и положительно сказывается на SEO, что приводит к лучшей индексации вашего контента и повышению видимости в поисковых системах.