Поддержка Проблемы и решения Как добиться идеального чпу?

  • Создан произвольный тип записи, где добавлена одна таксономия, как категория. Также созданы правила перезаписи, для отображения полной структуры ЧПУ, например:
    номе/post-type/term-parent/term-child/post-name

    Пытаюсь добавить, вторую таксономию, как теги, но чтобы я не делал, возникает 404 ошибка, либо структура ссылок ломается.

    Как это сделать правильно?

    <?php
    /*
    * Plugin Name: MOD
    * Description: DEV
    */
    
    /**
     * mod_cpt_services() -------------------- Создание произвольного типа записи.
     *
     * * cpt_services ------------------------ Регистрация типа записи.
     * * cpt_services_cat -------------------- Регистрация таксономии, как категорий.
     * * cpt_services_tag -------------------- Регистрация таксономии, как тега.
     *
     * permalink_services_cat() -------------- Структура ссылок для категорий.
     * rewrite_rules_services_cat() ---------- Генерация правил перезаписи ссылок для категорий.
     *
     * permalink_services_tag() -------------- Структура ссылок для тегов.
     * rewrite_rules_services_tag() ---------- Генерация правил перезаписи ссылок для тегов.
     *
     * reset_rewrite_rules() ----------------- Сброс правил перезаписи при создании/удалении/изменении категорий и тегов.
     */
    
    # mod_cpt_services()
    # 1
    add_action('init', 'mod_cpt_services', 0);
    function mod_cpt_services()
    {
      # cpt_services
        register_post_type('cpt_services', array(
            'labels'        => array('name' => 'Услуги',),
            'public'        => true,
            'menu_position' => 100,
        'menu_icon'     => 'dashicons-category',
            'rewrite'       => array('slug' => 'services', 'with_front' => false),
            'supports'      => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes', 'post-formats'),
            'query_var'     => true,
            'show_in_rest'  => true,
        ));
      # cpt_services_cat
        register_taxonomy('cpt_services_cat', array('cpt_services'), array(
            'labels'        => array( 'name' => 'Категории услуг',),
            'public'        => true,
            'hierarchical'  => true,
            'rewrite'       => array('slug' => 'services', 'hierarchical' => true, 'with_front' => false),
            'query_var'     => true,
            'show_in_rest'  => true,
        ));
      # cpt_services_tag
        register_taxonomy('cpt_services_tag', array('cpt_services'), array(
            'labels'        => array( 'name' => 'Теги услуг',),
            'public'        => true,
            'hierarchical'  => false,
            'rewrite'       => array('slug' => 'services', 'hierarchical' => true, 'with_front' => false),
            'query_var'     => true,
            'show_in_rest'  => true,
        ));
        flush_rewrite_rules();    
    }
    
    # permalink_services_cat()
    # 2
    add_filter('post_type_link', 'permalink_services_cat', 1, 2);
    function permalink_services_cat($permalink, $post)
    {
        if (strpos($permalink, 'services') === false) return $permalink;
        $terms = get_the_terms($post, 'cpt_services_cat');
        if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) {
            $taxonomy_slug = get_term_parents_list($terms[0]->term_id, 'cpt_services_cat', array(
                'separator' => '/', 'format' => 'slug', 'link' => false, 'inclusive' => true
            ));
            $taxonomy_slug = trim($taxonomy_slug, '/');
        } else {
            $taxonomy_slug = 'sandbox';
        }
        return str_replace('services', 'services/' . $taxonomy_slug, $permalink);
    }
    
    # rewrite_rules_services_cat()
    # 3
    add_filter('generate_rewrite_rules', 'rewrite_rules_services_cat');
    function rewrite_rules_services_cat($wp_rewrite)
    {
        $rules = array();
        $taxonomies = get_terms(array(
            'taxonomy' => 'cpt_services_cat', 'hide_empty' => false
        ));
        foreach ($taxonomies as $taxonomy) {
            $taxonomy_slug = get_term_parents_list($taxonomy->term_id, 'cpt_services_cat', array(
                'separator' => '/', 'format' => 'slug', 'link' => false, 'inclusive' => true
            ));
            $rules['^services/' . $taxonomy_slug . '?$'] = 'index.php?' . $taxonomy->taxonomy . '=' . $taxonomy->slug;
        }
        $rules['^services/([^/]*)/?$'] = 'index.php?cpt_services_cat=$matches[1]';
        $rules['^services/(.+?)/page/?([0-9]{1,})/?$'] = 'index.php?cpt_services_cat=$matches[1]&paged=$matches[2]';
        $rules['^services/(.+?)/([^/]*)/?$'] = 'index.php?cpt_services=$matches[2]';
        $wp_rewrite->rules = $rules + $wp_rewrite->rules;
    }
    
    /*
    # permalink_services_tag()
    # 4
    add_filter('post_type_link', 'permalink_services_tag', 1, 2);
    function permalink_services_tag($permalink, $post)
    {
        if (strpos($permalink, 'services') === false) return $permalink;
        $terms = get_the_terms($post, 'cpt_services_tag');
        if (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) {
            $taxonomy_slug = get_term_parents_list($terms[0]->term_id, 'cpt_services_tag', array(
                'separator' => '/', 'format' => 'slug', 'link' => false, 'inclusive' => true
            ));
            $taxonomy_slug = trim($taxonomy_slug, '/');
        } else {
            $taxonomy_slug = 'sandbox';
        }
        return str_replace('services', 'services/' . $taxonomy_slug, $permalink);
    }
    
    # rewrite_rules_services_tag()
    # 5
    add_filter('generate_rewrite_rules', 'rewrite_rules_services_tag');
    function rewrite_rules_services_tag($wp_rewrite)
    {
        $rules = array();
        $taxonomies = get_terms(array(
            'taxonomy' => 'cpt_services_tag', 'hide_empty' => false
        ));
        foreach ($taxonomies as $taxonomy) {
            $taxonomy_slug = get_term_parents_list($taxonomy->term_id, 'cpt_services_tag', array(
                'separator' => '/', 'format' => 'slug', 'link' => false, 'inclusive' => true
            ));
            $rules['^services/' . $taxonomy_slug . '?$'] = 'index.php?' . $taxonomy->taxonomy . '=' . $taxonomy->slug;
        }
        $rules['^services/([^/]*)/?$'] = 'index.php?cpt_services_tag=$matches[1]';
        $rules['^services/(.+?)/page/?([0-9]{1,})/?$'] = 'index.php?cpt_services_tag=$matches[1]&paged=$matches[2]';
        $rules['^services/(.+?)/([^/]*)/?$'] = 'index.php?cpt_services=$matches[2]';
        $wp_rewrite->rules = $rules + $wp_rewrite->rules;
    }
    */
    
    # reset_rewrite_rules()
    # 6
    # cpt_services_cat
    add_action('created_cpt_services_cat', 'reset_rewrite_rules');
    add_action('delete_cpt_services_cat', 'reset_rewrite_rules');
    add_action('edited_cpt_services_cat', 'reset_rewrite_rules');
    # cpt_services_tag
    add_action('created_cpt_services_tag', 'reset_rewrite_rules');
    add_action('delete_cpt_services_tag', 'reset_rewrite_rules');
    add_action('edited_cpt_services_tag', 'reset_rewrite_rules');
    function reset_rewrite_rules()
    {
        flush_rewrite_rules();
    }
    • Тема изменена 3 года, 8 месяцев назад пользователем Anatolii Dimov.
Просмотр 5 ответов — с 1 по 5 (всего 5)
  • Пытаюсь добавить, вторую таксономию, как теги, но чтобы я не делал, возникает 404 ошибка, либо структура ссылок ломается.

    Куда пытаетесь добавить и что по этому урл должно открываться? ( запись, категория или фильтрация записей по категории и метке)

    services

    Получается что у меток и категорий одинаковый префикс.

    Делайте разные префиксы.

    Если все же нужен одинаковый преф., то можно использовать
    фильтр add_filter(‘request’,

    Нужно будет проверять slug по базе

    Пример, проверяем slug в таксономии cpt_services_cat

    
    $term = get_term_by('slug', 'тут слаг из урл', 'cpt_services_cat');
    
    if($term ) {
    //если найдено, то изменить запрос
     $query_vars['cpt_services_cat'] = 'тут слаг из урл';
    
    //если не найдено ищем в метках
    } else {
    
    $term = get_term_by('slug', 'тут слаг из урл', 'cpt_services_tag');
    if($term ) {
    //если найдено, то изменить запрос
     $query_vars['cpt_services_tag'] = 'тут слаг из урл';
    }
    
    }

    Только до этих проверок, нужно будет сделать еще проверки урл, например вхождение services, чтобы не делать запросы там где не нужно.

    Привет, я рад что ты спросил. Я пытаюсь добавить, правило перезаписи для тегов.
    Код выше разбит на 6 блоков: 2-3 блоки — правило перезаписи категорий; 4-5 закомментированные блоки — правило перезаписи тегов, которые я и пытаюсь добавить.

    Мне необходимо изменить регулярное выражение для структуры ссылок для тегов 4-5, как эта:
    post-type/tagged/term-parent/term-child/post-name

    Ничего не понятно

     $rules['^services/([^/]*)/?$'] = 'index.php?cpt_services_tag=$matches[1]';
     $rules['^services/([^/]*)/?$'] = 'index.php?cpt_services_cat=$matches[1]'; 

    В таком виде и то и то работать не будет, будет что-то одно.

    Указывайте разные префиксы.

    'hierarchical' => false,

    у меток нету иерархии, по этому
    все это не нужно

    $taxonomies = get_terms(array(
            'taxonomy' => 'cpt_services_tag', 'hide_empty' => false
        ));
        foreach ($taxonomies as $taxonomy) {
            $taxonomy_slug = get_term_parents_list($taxonomy->term_id, 'cpt_services_tag', array(
                'separator' => '/', 'format' => 'slug', 'link' => false, 'inclusive' => true
            ));
            $rules['^services/' . $taxonomy_slug . '?$'] = 'index.php?' . $taxonomy->taxonomy . '=' . $taxonomy->slug;
        }

    и тут ‘rewrite’ => array(‘slug’ => ‘services’, ‘hierarchical’ => true, ‘with_front’ => false),

    ‘hierarchical’ => true можно убрать, так как нет смысла

    Большое вам спасибо за помощь. К сожалению у меня нет знаний в программировании, и я всё делаю методом тыка. Три недели уже тыкаю, да всё не туда.

    Да вы правы, что если изменить ‘rewrite’ => array( ‘slug’ => ‘services1’), и заменить его в 4-5 блоках, то всё работает. Однако, мне необходимо структура ссылок, которую я описывал выше, а также если перейти на уровень вверх, то структура не ломается (home/child-3/).

    Я предполагаю, что нужно объединить блоки 3-5 (cattag), тоесть cpt_services_taxonomy, в котором сделать примерно следующие:

    $rules['^services/([^/]*)/[ тег если есть ]/?$'] = 'index.php?cpt_services_taxonomy=$matches[1]';

    В любом случаи, вы мне уже помогли сдвинутся с места.

    • Ответ изменён 3 года, 8 месяцев назад пользователем Anatolii Dimov.
    • Ответ изменён 3 года, 8 месяцев назад пользователем Anatolii Dimov.
Просмотр 5 ответов — с 1 по 5 (всего 5)
  • Тема «Как добиться идеального чпу?» закрыта для новых ответов.