• Hello WordPress!
    Created a custom post type with one taxonomy added as a category. Overwrite rules have also been created to display the complete structure of the CNC, for example:
    home/post-type/term-parent/term-child/post-name

    I am trying to add a second taxonomy like tags, but whatever I do, I get a 404 error or the link structure breaks.

    Can someone help me with this?

    <?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();
    }

    I apologize for my english. I am writing to you via google translator.
    Glad for any help. Other solutions are also welcome.

    Same question at Stack

Viewing 3 replies - 1 through 3 (of 3 total)
  • Moderator bcworkz

    (@bcworkz)

    You cannot have the same rewrite regexp for both services-cat and services-tag. WP will always match one and never the other. There needs to be some distinct difference in the regexp. For example, tag URLs structured like post-type/tagged/term-parent/term-child/post-name

    BTW, Google usually does a pretty good job translating Russian to English. It speaks English better than some native English speakers ??

    Thread Starter Anatolii Dimov

    (@xpood)

    Thanks for the help. I really appreciate this. Unfortunately my programming skills are very limited. Can you please help me write a regex. At least roughly indicate the lines where you need to change.

    I understand that I need to change the link structure for tags, and also something will need to be changed in the categories. Please, help. For three weeks now I have been trying to find a solution. Boil the grains.

    Moderator bcworkz

    (@bcworkz)

    The main issue is the category and tag base portions (the part that’s not variable, in this case “services”) cannot have the post type’s base in common. There must be something unique about each base. For example, use “services”, “services/cat”, and “services/tag”. An example line of code for services categories:
    $rules['^services/cat/([^/]*)/?$'] = 'index.php?cpt_services_cat=$matches[1]';

    The post type base must be added last or WP will try to find services posts named “cat” or “tag”. When a cat or tag URL is requested, it needs to match the correct regexp before it reaches the “services” base regexp. The order in which action callbacks are called is somewhat undefined. To ensure one is called before the other, use the $priority argument of add_action() to manage the order callbacks are called. Larger priority number gets called later.

    You don’t want to call flush_rewrite_rules() on every request. It’s extremely resource intensive and will slow down your site. It should only be called when your theme or plugin is activated. You can leave it in place while developing rewrite rules, just don’t leave it that way. Or take it out now and visit the permalinks settings screen in order to flush rewrite rules.

    I doubt that it matters, but what you put into Google translate that it translated as “Boil the grains.” is apparently a Russian idiom which makes no sense in English in this context. It’s more amusing than anything, but be aware that machine translations of idioms rarely make sense ??

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘How do I get the correct URL?’ is closed to new replies.