Вопрос или проблема
У меня длительная проблема, и я надеюсь на вашу помощь.
У меня есть пользовательская таксономия “город” (она не иерархическая, как теги).
Я просто хотел бы, чтобы мои URL выглядели так:
/%city%/%category%/%postname%/
Так что вот, что я хочу добиться.
http://example.com/city/moscow
– Показать все записи в таксономии город-Москва.http://example.com/category/shopping
– Показать все записи в этой категории и во всех городах.http://example.com/category/shopping/supermarket
– Показать все записи в этой категории и во всех городах.http://example.com/moscow/shopping/
– Показать все записи в этой категории в Москве.http://example.com/moscow/shopping/supermarket/
– Показать все записи в этой дочерней категории в Москве.http://example.com/moscow/shopping/supermarket/postname
– Показать запись.
Я сделал следующее:
- Сначала я создал пользовательскую таксономию – город.
- Я добавил код в function.php
function add_custom_taxonomies_city() {
register_taxonomy('city', 'post', array(
'hierarchical' => false,
'labels' => array(
'name' => _x( 'Город', 'таксономия общее имя' ),
'search_items' => __( 'Искать города' ),
'all_items' => __( 'Все города' ),
'parent_item' => __( 'Родительские категории' ),
'parent_item_colon' => __( 'Родительские категории:' ),
'edit_item' => __( 'Редактировать город' ),
'update_item' => __( 'Обновить город' ),
'add_new_item' => __( 'Добавить город' ),
'new_item_name' => __( 'Новый город' ),
'menu_name' => __( 'города' ),
);
),
'rewrite' => array(
'slug' => 'city',
'with_front' => false,
'hierarchical' => false
),
));
}
add_action( 'init', 'add_custom_taxonomies_city', 0 );
add_filter('post_link', 'town_permalink', 10, 3);
add_filter('post_type_link', 'town_permalink', 10, 3);
function town_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%city%') === FALSE) return $permalink;
// Получить запись
$post = get_post($post_id);
if (!$post) return $permalink;
// Получить термины таксономии
$terms = wp_get_object_terms($post->ID, 'city');
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug;
else $taxonomy_slug = 'not-city';
return str_replace('%city%', $taxonomy_slug, $permalink);
}
Результат:
http://example.com/city/moscow
– Работаетhttp://example.com/category/shopping
– Работаетhttp://example.com/category/shopping/supermarket/
– Работаетhttp://example.com/moscow/shopping/
– Работаетhttp://example.com/moscow/shopping/supermarket/
– Не работает!!!!!http://example.com/moscow/shopping/supermarket/postname
– Не работает!!!!!
Этот пост имеет следующую ссылку: http: //mysite.ru/ moscow/shopping/postname
Но мне нужно, чтобы ссылки содержали дочернюю категорию.
- Я попробовал решить задачу с другой опцией: я добавил следующий код в function.php
function addRoutes() {
add_rewrite_tag('%city%', '(.+?)');
add_rewrite_rule('(.+?)/(.+?)/([^/]+)(/[0-9]+)?/?$', 'index.php?city=$matches[1]&category_name=$matches[2]&name=$matches[3]&page=$matches[4]', 'top');
add_rewrite_rule('(.?.+?)(/[0-9]+)?/?$', 'index.php?pagename=$matches[1]&page=$matches[2]', 'top');
flush_rewrite_rules();
}
add_action('init', 'addRoutes');
В результате
http://example.com/city/moscow
– Ошибка 404.
http://example.com/category/shopping
– Ошибка 404.
http://example.com/category/shopping/supermarket/
– Ошибка 404.
http://example.com/moscow/shopping/supermarket/postname
– Ошибка 400
Кажется, система не понимает %city%
Что не так?
Жду вашей помощи
Может кто-нибудь помочь мне?
Большое спасибо!
Я решил изменить структуру URL на:
example.com/city/moscow/category/shopping/
– Показать все записи в этой категории в Москве.example.com/city/moscow/category/shopping/supermarket/
– Показать все записи в этой дочерней категории в Москве.example.com/city/moscow/category/shopping/supermarket/postname
– Показать запись.
Код:
//Правила переписывания function eg_add_query_vars( $query_vars ) { $new_vars = array( 'town' ); return array_merge( $new_vars, $query_vars ); } add_filter( 'query_vars', 'eg_add_query_vars' ); function eg_add_rewrite_rules() { global $wp_rewrite; $new_rules = array( 'city/(.+?)/category/(.+?)/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2), "city/(.+?)/category/(.+?)/(.+?)/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2) . "&category_name=". $wp_rewrite->preg_index(3), //"city/(.+?)/category/(.+?)/(.+?)/(.+?)/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2) . "&category_name=". $wp_rewrite->preg_index(3). "&page=". $wp_rewrite->preg_index(4),// Это моё усилие написать правило для постов (не работает) ); $wp_rewrite->rules = $new_rules + $wp_rewrite->rules; } add_action( 'generate_rewrite_rules', 'eg_add_rewrite_rules' ); //создание постоянной ссылки: function city_permalink($permalink, $post_id, $leavename) { if (strpos($permalink, '%city%') === FALSE) return $permalink; // Получить пост $post = get_post($post_id); if (!$post) return $permalink; // Получить термины таксономии $terms = wp_get_object_terms($post->ID, 'town'); if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) $taxonomy_slug = $terms[0]->slug; else $taxonomy_slug = 'not-city'; return str_replace('%town%', $taxonomy_slug, $permalink);} function wp_town_query( $query ) { if( isset( $query->query_vars['city'] ) ): if( $city = get_term_by( 'id', $query->query_vars['city'], 'city' ) ) $query->query_vars['town'] = $city->slug; endif; } add_action( 'parse_query', 'wp_city_query' );
Мои настройки на странице администрирования Постоянные ссылки:
city/%city%/category/%category%/%postname%/
В результате я имею:
– example.com/city/moscow/category/shopping/
– работает
– example.com/city/moscow/category/shopping/supermarket/
– работает
но я все еще не могу понять, как написать правило для постов:
– example.com/city/moscow/category/shopping/supermarket/postname
– не работает.
Пагинация тоже не работает.
Я буду рад любым советам!
Это работает:
'city/(.+?)/category/(.+?)/(.+?)/([^/]+)/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2). "&category_name=" . $wp_rewrite->preg_index(3). "&name=" . $wp_rewrite->preg_index(4), "city/(.+?)/category/(.+?)/page/?([0-9]{1,})/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2). "&paged=' . $wp_rewrite->preg_index(3), 'city/(.+?)/category/(.+?)/?$' => 'index.php?city=' . $wp_rewrite->preg_index(1) . '&category_name=" . $wp_rewrite->preg_index(2),
Хорошо, я получу отрицательные баллы за это, но это должно решить вашу проблему, пожалуйста, не сердитесь на меня.
Прежде чем кто-то даст мне минус за это, я должен сказать, что я не имею ничего общего с разработчиками этого плагина:
Для пользовательских таксономий и пользовательских типов записей я часто использую плагин под названием “Types“. Вы можете найти его в списке установленных плагинов в меню WordPress, и он должен решить вашу проблему без кодирования.
Ответ или решение
Настройка пользовательской таксономии и ЧПУ в WordPress
У вас есть задача настроить пользовательскую таксономию "город" (city) в WordPress и выстроить для неё удобные и понятные URL-адреса. Ниже приведены шаги, которые помогут вам правильно реализовать вашу конфигурацию.
Шаг 1: Регистрация пользовательской таксономии
Вы уже создали пользовательскую таксономию "город" с помощью следующего кода в functions.php
:
function add_custom_taxonomies_city() {
register_taxonomy('city', 'post', array(
'hierarchical' => false,
'labels' => array(
'name' => _x('City', 'taxonomy general name'),
'search_items' => __('Search cities'),
'all_items' => __('All cities'),
'edit_item' => __('Edit city'),
'update_item' => __('Update city'),
'add_new_item' => __('Add city'),
'new_item_name' => __('New city'),
'menu_name' => __('cities'),
),
'rewrite' => array(
'slug' => 'city',
'with_front' => false,
'hierarchical' => false
),
));
}
add_action('init', 'add_custom_taxonomies_city', 0);
Это правильный подход. Убедитесь, что таксономия регистрируется до вашего кода для создания ЧПУ.
Шаг 2: Настройка структуры URL
Для достижения желаемой структуры URL /%city%/%category%/%postname%/
, вы должны изменить правила переписывания. Ваш изначальный код для создания правил выглядит многообещающе, но нуждается в доработке.
Корректировка правил переписывания
- Замените ваш код для добавления правил:
function addRoutes() {
add_rewrite_tag('%city%', '(.+?)');
add_rewrite_rule('^city/([^/]+)/category/([^/]+)/?$', 'index.php?city=$matches[1]&category_name=$matches[2]', 'top');
add_rewrite_rule('^city/([^/]+)/category/([^/]+)/([^/]+)/?$', 'index.php?city=$matches[1]&category_name=$matches[2]&name=$matches[3]', 'top');
flush_rewrite_rules(); // Важно: вызовите очищение правил переписывания
}
add_action('init', 'addRoutes');
- Обратите внимание на
flush_rewrite_rules()
. Этот вызов следует использовать с осторожностью и не в каждомinit
, а только при необходимости (например, после изменения правил). Лучше вызвать его в админке, например, через кнопку.
Шаг 3: Формирование ссылок для постов
Для изменения формата ссылок на посты в соответствии с выбранной структурой:
add_filter('post_link', 'town_permalink', 10, 3);
add_filter('post_type_link', 'town_permalink', 10, 3);
function town_permalink($permalink, $post_id, $leavename) {
if (strpos($permalink, '%city%') === false) return $permalink;
$post = get_post($post_id);
if (!$post) return $permalink;
$terms = wp_get_object_terms($post->ID, 'city');
if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) {
$taxonomy_slug = $terms[0]->slug;
} else {
$taxonomy_slug = 'not-city';
}
return str_replace('%city%', $taxonomy_slug, $permalink);
}
Убедитесь, что в ваших настройках постоянных ссылок выбран формат /%city%/%category%/%postname%/
.
Шаг 4: Обработка запроса
Вам нужно обработать запрос, чтобы WordPress корректно распознавал ваши новые параметры URL:
add_action('pre_get_posts', 'wp_city_query');
function wp_city_query($query) {
if ($query->is_main_query() && !is_admin() && isset($query->query_vars['city'])) {
$city = $query->query_vars['city'];
$query->set('tax_query', array(
array(
'taxonomy' => 'city',
'field' => 'slug',
'terms' => $city,
),
));
}
}
Шаг 5: Проверка и отладка
После всех изменений проверьте, что у вас нет ошибок 404, и убедитесь, что система обрабатывает запросы как ожидается. Возможно, потребуется очищение кеша, если он установлен на сайте.
Заключение
Следуя указанным шагам, вы сможете настроить пользовательскую таксономию и правильную структуру пользовательских URL в WordPress. Помните про необходимость периодического очищения правил переписывания, особенно после внесения изменений в настройки URL. Этот обратный путь не требует применения сторонних плагинов и поддерживает чистоту вашего кода.