Постоянные ссылки для кастомного типа записи в WordPress: как правильно создать?
Салют всем. Я создаю постоянные динамические ссылки в WordPress вида: домен/страна/город/университет. По типу как здесь: https://ischoolconnect.com/en/universities/usa/mas...
Имеется:
index.php – каталог с университетами
university.php – страница университета и описанием:
<?php /* Template Name: University Template */ ?> |
<?php /* Template Name: University Template */ ?>
Что я делаю
1. Для достижения нужной структуры ссылок в functions.php:
/* Start: Register Post Type (Universities Pages) */ function custom_post_type_universities_pages() { $labels = array( 'name' => _x('Universities Pages', 'post type general name', 'wp-universities'), 'singular_name' => _x('Universities Page', 'post type singular name', 'wp-universities'), ); $args = array( 'labels' => $labels, 'public' => true, 'supports' => array('title','editor','author','comments'), 'rewrite' => array('slug' => 'country/city/university'), ); register_post_type('universities_page', $args); } add_action('init', 'custom_post_type_universities_pages'); /* Start: Rewrite URL's */ function custom_rewrite_tags() { add_rewrite_tag('%country%', '([^&]+)'); add_rewrite_tag('%city%', '([^&]+)'); add_rewrite_tag('%university%', '([^&]+)'); } add_action('init', 'custom_rewrite_tags'); function custom_rewrite_rules() { add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); } add_action('init', 'custom_rewrite_rules'); |
/* Start: Register Post Type (Universities Pages) */ function custom_post_type_universities_pages() { $labels = array( 'name' => _x('Universities Pages', 'post type general name', 'wp-universities'), 'singular_name' => _x('Universities Page', 'post type singular name', 'wp-universities'), ); $args = array( 'labels' => $labels, 'public' => true, 'supports' => array('title','editor','author','comments'), 'rewrite' => array('slug' => 'country/city/university'), ); register_post_type('universities_page', $args); } add_action('init', 'custom_post_type_universities_pages'); /* Start: Rewrite URL's */ function custom_rewrite_tags() { add_rewrite_tag('%country%', '([^&]+)'); add_rewrite_tag('%city%', '([^&]+)'); add_rewrite_tag('%university%', '([^&]+)'); } add_action('init', 'custom_rewrite_tags'); function custom_rewrite_rules() { add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); } add_action('init', 'custom_rewrite_rules');
2. На странице index.php:
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"> <?php echo esc_html($university_data->name); ?> </a> |
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"> <?php echo esc_html($university_data->name); ?> </a>
3. Устанавливаю кастомные пермалинки в WordPress: домен//%country%/%city%/%university%/
4. В админ панели в разделе Страницы создаю страницу University Page с постоянной ссылкой «university» и шаблоном «University Template»
5. Размещаю в шапке на странице university.php:
<?php /* Template Name: University Template */ // map this template to a page that has the slug "custom-page" $country = get_query_var('country'); $city = get_query_var('city'); $university = get_query_var('university'); get_header(); ?> <!-- Запрос к БД --> <?php // Получение значения slug из URL $slug = isset($wp_query->query_vars['university_slug']) ? sanitize_text_field($wp_query->query_vars['university_slug']) : ''; // Проверка наличия slug if ($slug) { global $wpdb; // Запрос для получения информации о университете по slug $query = $wpdb->prepare("SELECT u.*, l.file_path, a.country, a.city, r.global, r.regional, r.qs, r.times, r.us_news FROM {$wpdb->prefix}universities u LEFT JOIN {$wpdb->prefix}logos l ON u.university_id = l.university_id LEFT JOIN {$wpdb->prefix}address a ON u.university_id = a.university_id LEFT JOIN {$wpdb->prefix}rank r ON u.university_id = r.university_id WHERE u.slug = %s", $slug); $university_data = $wpdb->get_row($query); ?> |
<?php /* Template Name: University Template */ // map this template to a page that has the slug "custom-page" $country = get_query_var('country'); $city = get_query_var('city'); $university = get_query_var('university'); get_header(); ?> <!-- Запрос к БД --> <?php // Получение значения slug из URL $slug = isset($wp_query->query_vars['university_slug']) ? sanitize_text_field($wp_query->query_vars['university_slug']) : ''; // Проверка наличия slug if ($slug) { global $wpdb; // Запрос для получения информации о университете по slug $query = $wpdb->prepare("SELECT u.*, l.file_path, a.country, a.city, r.global, r.regional, r.qs, r.times, r.us_news FROM {$wpdb->prefix}universities u LEFT JOIN {$wpdb->prefix}logos l ON u.university_id = l.university_id LEFT JOIN {$wpdb->prefix}address a ON u.university_id = a.university_id LEFT JOIN {$wpdb->prefix}rank r ON u.university_id = r.university_id WHERE u.slug = %s", $slug); $university_data = $wpdb->get_row($query); ?>
Что ожидание: после внесения изменений в код при клике на ссылку
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"><?php echo esc_html($university_data->name); ?></a> |
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"><?php echo esc_html($university_data->name); ?></a>
открывается страница университета university.php c URL домен/страна/город/страница университета.
Что получаю: после внесения изменений в код при клике на ссылку
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"><?php echo esc_html($university_data->name); ?></a> |
<a href="<?php echo home_url($university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>"><?php echo esc_html($university_data->name); ?></a>
открывается страница index.php c URL домен/страна/город/страница университета.
Вопрос: Где допущена ошибка? Ввиду моих, на момент написания вопроса, малых знаний в WordPress полагаю, что при перезаписи и использовании функций «rewrite_tag» и «rewrite_rule».
Ориентировался при решении вопроса на статью.
Дополнительно
Проверка наличия slug
точно внутрь заходит и находит данные в бд?
1. путь к контенту - задача хлебных крошек, а не урла
2. ХК и урл - вещи не зависимые.
и тогда жизнь станет намного легче. И твоя и жизнь сайта.
А "постоянные динамические ссылки" - это отдельный оксюморонный писец :)
И да верный путь - правильно создать кастомные типы контента и отказаться от бреда "путь в урле".
какая альтернатива для задачи?
Я не знаю реальную задачу, но ты точно не читатель.
Повторяю:
правильно создать каcтомные типы контента и отказаться от бреда "путь в урле".
Даниело Фронтендье @daniloneil Автор вопроса UPD: нашёл решение самостоятельно, всем спасибо за комментарии.
Вот исправленный порядок и код:
Для function.php
/* Start: Register Post Type (Universities Pages) */ function custom_post_type_universities_pages() { $labels = array( 'name' => _x('Universities Pages', 'post type general name', 'your-text-domain'), 'singular_name' => _x('Universities Page', 'post type singular name', 'your-text-domain'), // Добавьте другие метки по вашему усмотрению ); $args = array( 'labels' => $labels, 'public' => true, 'supports' => array('title','editor','author','comments'), // Включение поддержки комментариев ); register_post_type('universities_page', $args); } add_action('init', 'custom_post_type_universities_pages'); /* Start: Rewrite URL's */ function custom_rewrite_rule() { add_rewrite_rule('^([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?pagename=university&country=$matches[1]&city=$matches[2]&university_slug=$matches[3]', 'top'); } add_action('init', 'custom_rewrite_rule'); function custom_rewrite_tag() { add_rewrite_tag('%country%', '([^&]+)'); add_rewrite_tag('%city%', '([^&]+)'); add_rewrite_tag('%university_slug%', '([^&]+)'); } add_action('init', 'custom_rewrite_tag'); |
/* Start: Register Post Type (Universities Pages) */ function custom_post_type_universities_pages() { $labels = array( 'name' => _x('Universities Pages', 'post type general name', 'your-text-domain'), 'singular_name' => _x('Universities Page', 'post type singular name', 'your-text-domain'), // Добавьте другие метки по вашему усмотрению ); $args = array( 'labels' => $labels, 'public' => true, 'supports' => array('title','editor','author','comments'), // Включение поддержки комментариев ); register_post_type('universities_page', $args); } add_action('init', 'custom_post_type_universities_pages'); /* Start: Rewrite URL's */ function custom_rewrite_rule() { add_rewrite_rule('^([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?pagename=university&country=$matches[1]&city=$matches[2]&university_slug=$matches[3]', 'top'); } add_action('init', 'custom_rewrite_rule'); function custom_rewrite_tag() { add_rewrite_tag('%country%', '([^&]+)'); add_rewrite_tag('%city%', '([^&]+)'); add_rewrite_tag('%university_slug%', '([^&]+)'); } add_action('init', 'custom_rewrite_tag');
Для index.php:
<a href="<?php echo home_url('/' . $university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>" class="text-size-medium text-weight-bold"><?php echo esc_html($university_data->name); ?></a> |
<a href="<?php echo home_url('/' . $university_data->country . '/' . $university_data->city . '/' . $university_data->slug); ?>" class="text-size-medium text-weight-bold"><?php echo esc_html($university_data->name); ?></a>
Для кастомной структуры в админ панели:
домен/%country%/%city%/%postname%/
- т.е. мой второй вариант, только реализованный через имя страницы напрямую, а не через ID, получаемый по имени страницы
Ответы:
Я создаю постоянные динамические ссылки
Чет или я не понимаю в жизни, или вы.
1) Есть ссылки постоянные. Обычно они строятся на основании числовых индексов объектов.
2) Есть ссылки динамические. Обычно они строятся на основании slug представлений сущностей.
Отличие первых от вторых в том, что если имя/название у сущности поменяется, соответственно слаг перегенерируется и динамическая ссылка будет вести на 404, а постоянная останется живой.
Пример - заголовок новости, который поменяли и изменили слаг. В соцсети всегда постят постоянную ссылку, а на сайт отдают списки с динамическими, так все желающие и из СС и с сайта напрямую попадут куда надо.
- совершеннно верно. Изменил тему вопроса на: "Постоянные ссылки для кастомного типа записи в WordPress: как правильно создать". Суть вопроса остаётся прежней.
- Даниело Фронтендье, Постоянные ссылки не должны содержать слагов.
- ThunderCat, окей, подскажите, плис, как тогда верно переформулировать мой вопрос, если мне надо создать постоянные ссылки к виду домен/страна/город/университет для для кастомного типа записи?
- Даниело Фронтендье, я не эксперт в вордпрессе, просто указал что в рамках вебразработки у вас концептуальная ошибка. В рамках кода - слишком много специфичного функционального кода, в котором надо разбираться. Я тут ничем не помогу.
IvanU7n @IvanU7n несовместимые хотелки: сдаётся мне, что в текущей конфигурации будет использоваться archive-universities_page.php из темы
чтобы использовался single-universities_page.php из темы:
- add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); + add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&slug=$matches[3]', 'top'); |
- add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); + add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&slug=$matches[3]', 'top');
чтобы использовался шаблон, назначенный для страницы university:
- add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); + add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?page_id='.get_page_by_path('university')->ID.'&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); |
- add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?post_type=universities_page&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top'); + add_rewrite_rule('([^/]+)/([^/]+)/([^/]+)/?$', 'index.php?page_id='.get_page_by_path('university')->ID.'&country=$matches[1]&city=$matches[2]&university=$matches[3]', 'top');
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос


Для структуры URL вида
/страна/город/университет/одного шаблона страницы недостаточно. В WordPress постоянные ссылки должны быть связаны с типом записи, rewrite rules и данными, из которых берутся страна и город. Если делать это через обычные страницы и произвольные ссылки, быстро появятся конфликты с другими страницами, архивами и 404.Более правильная схема: создать custom post type
university, хранить страну и город как таксономии или meta-поля, а ссылку формировать черезpost_type_link. Желательно оставить постоянный префикс, например:/universities/usa/boston/harvard/
URL без префикса красивее, но рискованнее: WordPress должен отличать университет от обычной страницы верхнего уровня, рубрики, записи и служебного endpoint.
Пример регистрации CPT:
register_post_type('university', [ 'public' => true, 'has_archive' => 'universities', 'rewrite' => [ 'slug' => 'universities/%country%/%city%', 'with_front' => false, ], 'supports' => ['title', 'editor', 'thumbnail'], ]);
Затем плейсхолдеры в ссылке заменяются значениями конкретной записи. После изменения правил нужно один раз обновить постоянные ссылки в админке. Делать
flush_rewrite_rules()на каждом запросе нельзя: это лишняя нагрузка.single-university.php, а не обычный page template.Если каталог большой, страну и город лучше делать таксономиями: так проще строить архивы, фильтры и хлебные крошки.