Постоянные ссылки для кастомного типа записи в WordPress: как правильно создать?

Ссылка скопирована
1 ответ

Салют всем. Я создаю постоянные динамические ссылки в 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

точно внутрь заходит и находит данные в бд?

  • maksam07, да, дебаг показывает, что принимает то, что отдаёт БД.
  • Достаточно понимать два фактора:
    1. путь к контенту - задача хлебных крошек, а не урла
    2. ХК и урл - вещи не зависимые.
    и тогда жизнь станет намного легче. И твоя и жизнь сайта.

    А "постоянные динамические ссылки" - это отдельный оксюморонный писец :)

    И да верный путь - правильно создать кастомные типы контента и отказаться от бреда "путь в урле".

  • Refguser, окей, я создал кастомные типы записей, моя задача – чтобы URL выглядел домен/страна/город/университет, тем самым, у меня при открытии домен/страна/ будут отображаться все универы по стране, домен/страна/город/ все универы в городе. В какую сторону лежать чтобы разобраться в вопросе?
  • Даниело Фронтендье, ну если всё ещё не понял, то последний раз: "задача – чтобы URL выглядел домен/страна/город/университет," - это идиотская задача.
  • Refguser, какая альтернатива для задачи? Ведь здесь всё работает как надо: https://ischoolconnect.com/en/universities/usa/mas.... В чём может быть проблема при создании данного типа в WP?
  • Даниело Фронтендье,

    какая альтернатива для задачи?

    Я не знаю реальную задачу, но ты точно не читатель.
    Повторяю:

    правильно создать каcтомные типы контента и отказаться от бреда "путь в урле".

  • Постоянные ссылки для кастомного типа записи в WordPress: как правильно создать?

    Даниело Фронтендье @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, окей, подскажите, плис, как тогда верно переформулировать мой вопрос, если мне надо создать постоянные ссылки к виду домен/страна/город/университет для для кастомного типа записи?
    • Даниело Фронтендье, я не эксперт в вордпрессе, просто указал что в рамках вебразработки у вас концептуальная ошибка. В рамках кода - слишком много специфичного функционального кода, в котором надо разбираться. Я тут ничем не помогу.

    Постоянные ссылки для кастомного типа записи в WordPress: как правильно создать?

    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');

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Юрий Linux Ответ

    Для структуры URL вида /страна/город/университет/ одного шаблона страницы недостаточно. В WordPress постоянные ссылки должны быть связаны с типом записи, rewrite rules и данными, из которых берутся страна и город. Если делать это через обычные страницы и произвольные ссылки, быстро появятся конфликты с другими страницами, архивами и 404.

    Более правильная схема: создать custom post type university, хранить страну и город как таксономии или meta-поля, а ссылку формировать через post_type_link. Желательно оставить постоянный префикс, например:

    /universities/usa/boston/harvard/

    /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'],
    ]);

    register_post_type('university', [ 'public' => true, 'has_archive' => 'universities', 'rewrite' => [ 'slug' => 'universities/%country%/%city%', 'with_front' => false, ], 'supports' => ['title', 'editor', 'thumbnail'], ]);

    Затем плейсхолдеры в ссылке заменяются значениями конкретной записи. После изменения правил нужно один раз обновить постоянные ссылки в админке. Делать flush_rewrite_rules() на каждом запросе нельзя: это лишняя нагрузка.

    • Страна и город должны иметь стабильные slug, а не произвольные названия.
    • Нужно проверять соответствие URL записи, чтобы не было дублей.
    • Для страницы университета используйте шаблон single-university.php, а не обычный page template.

    Если каталог большой, страну и город лучше делать таксономиями: так проще строить архивы, фильтры и хлебные крошки.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно