Как создать структуру постоянных ссылок с пользовательскими таксономиями и пользовательскими типами записей, такими как базовое имя/родительский налог/дочерний налог/пользовательское имя типа записи


Я прочесывал этот сайт и Google в поисках ответа, и я пришел совершенно пустой. В принципе, я хочу сделать именно то, что просит этот пост, но мне нужна иерархическая таксономия. Ответ, данный в этом посте, отлично работает, но только с одноуровневой таксономией. Возможно ли делать то, что я хочу? Я перепробовал миллион вещей, но ни одна из них не работает, в лучшем случае я могу получить правильные постоянные ссылки, но они выходят 404.

Чтобы наглядно проиллюстрировать, что я хотите:

/basename/ - ideally a page, but I think this will cause a permalink collision    
/basename/top-cat/ - top parent custom taxonomy archive    
/basename/top-cat/child-cat/ - child cat custom taxonomy archive     
/basename/top-cat/child-cat/grandchild-cat/ - grandchild cat custom taxonomy archive    
/basename/top-cat/child-cat/grandchild-cat/post-name/ - my custom post type post

Вы можете сделать это прекрасно с помощью встроенных записей и категорий, как вы это делаете с пользовательскими таксономиями и пользовательскими типами записей? Я знаю, что вам нужно использовать 'rewrite' => array( 'slug' => 'tax-name', 'with_front' => true, 'hierarchical' => true ), для получения иерархических слизней, что отлично работает на страницах архива, но сообщения пользовательского типа сообщений составляют 404. Если я удалю часть 'hierarchical' => true, то сообщения будут работать, но я потеряю иерархические URL-адреса (только /базовое имя/внук-кошка/имя поста/работает).

Итак, какие-нибудь решения? Большое вам спасибо, это было так увлекательно я схожу с ума уже около 3 недель.

Author: Community, 2012-01-20

3 answers

После объединения нескольких фрагментов других ответов у меня получилось! Итак, вот решение для тех из вас, кто тоже борется с этим:

Этот пост и этот немного помогли мне, так что спасибо этим ребятам.

Обратите внимание, что весь этот код, а также ваш первоначальный пользовательский тип записи и регистрационный код таксономии содержатся в вашем файле functions.php.

Сначала исправьте свои ошибки при определении пользовательских типов записей и таксономий: для пользовательских тип записи должен быть basename/%taxonomy_name%, а слаг для вашей таксономии должен быть просто basename. Не забудьте также добавить 'hierarchical' => true в массив перезаписи таксономии, чтобы получить вложенные термины в вашем URL-адресе. Также убедитесь, что для query_var установлено значение true в обоих случаях.

Вам нужно добавить новое правило перезаписи, чтобы WordPress знал, как интерпретировать вашу структуру URL-адресов. В моем случае пользовательская часть типа записи uri всегда будет 5-м сегментом uri, поэтому я соответствующим образом определил свое правило соответствия. Обратите внимание, что вам, возможно, придется изменить это если вы используете больше или меньше сегментов uri. Если у вас будут разные уровни вложенных терминов, вам нужно будет написать функцию, чтобы проверить, является ли последний сегмент uri пользовательским типом записи или термином таксономии, чтобы узнать, какое правило добавить (спросите меня, нужна ли вам помощь в этом).

add_filter('rewrite_rules_array', 'mmp_rewrite_rules');
function mmp_rewrite_rules($rules) {
    $newRules  = array();
    $newRules['basename/(.+)/(.+)/(.+)/(.+)/?$'] = 'index.php?custom_post_type_name=$matches[4]'; // my custom structure will always have the post name as the 5th uri segment
    $newRules['basename/(.+)/?$']                = 'index.php?taxonomy_name=$matches[1]'; 

    return array_merge($newRules, $rules);
}

Затем вам нужно добавить этот код, чтобы разрешить workpress обрабатывать %taxonomy_name% в пользовательском типе записи переписать структуру слага:

function filter_post_type_link($link, $post)
{
    if ($post->post_type != 'custom_post_type_name')
        return $link;

    if ($cats = get_the_terms($post->ID, 'taxonomy_name'))
    {
        $link = str_replace('%taxonomy_name%', get_taxonomy_parents(array_pop($cats)->term_id, 'taxonomy_name', false, '/', true), $link); // see custom function defined below
    }
    return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);

Я создал пользовательскую функцию на основе собственного Wordpress get_category_parents:

// my own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {    
    $chain = '';   
    $parent = &get_term($id, $taxonomy);

    if (is_wp_error($parent)) {
        return $parent;
    }

    if ($nicename)    
        $name = $parent -> slug;        
else    
        $name = $parent -> name;

    if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {    
        $visited[] = $parent -> parent;    
        $chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited);

    }

    if ($link) {
        // nothing, can't get this working :(
    } else    
        $chain .= $name . $separator;    
    return $chain;    
}

Затем вам нужно очистить ваши постоянные ссылки (просто загрузите страницу настроек постоянных ссылок).

Теперь, надеюсь, все "должно" работать! Пойдите, составьте кучу терминов таксономии и вложите их правильно, затем сделайте несколько пользовательских записей типа записей и правильно их классифицируйте. Вы также можете создать страницу со слизняком basename, и все должно работать так, как я указал в своем вопросе. Возможно, вам захочется создать несколько пользовательских страниц архива таксономии, чтобы контролировать их внешний вид и добавить некоторые своего рода виджет таксономии плагин для отображения вложенных категорий на боковой панели.

Надеюсь, это поможет вам!

 77
Author: Jeff, 2017-06-23 17:04:44

Взгляните на этот плагин ( теперь на github). Он предоставляет иерархические URL-адреса для категорий, но вы можете легко адаптироваться к любой таксономии.

Создание правила следует рекурсивной функции .

 3
Author: vmassuchetto, 2020-10-02 06:01:21

Для работы с различным уровнем вложенности,

/basename/top-cat/ -> Top Cat Archive
/basename/top-cat/post-name/ -> Post in Top Cat
/basename/top-cat/child-cat/ -> Child Cat Archive
/basename/top-cat/child-cat/post-name/ -> Post in Child Cat

В итоге я использовал решение Джеффа без фильтра rewrite_rules_array. Вместо этого я использовал фильтр request, чтобы проверить, является ли последняя часть URL-адреса допустимым именем сообщения, и добавить ее в query_vars.

Например.

function vk_query_vars($qvars){
    if(is_admin()) return $qvars;
    $custom_taxonomy = 'product_category';
    if(array_key_exists($custom_taxonomy, $qvars)){
        $custom_post_type = 'product';


        $pathParts = explode('/', $qvars[$custom_taxonomy]);
        $numParts = sizeof($pathParts);

        $lastPart = array_pop($pathParts);
        $post = get_page_by_path($lastPart, OBJECT, $custom_post_type);
        if( $post && !is_wp_error($post) ){
            $qvars['p'] = $post->ID;
            $qvars['post_type'] = $custom_post_type;
        }
    }
    return $qvars;
}
add_filter('request', 'vk_query_vars');
 1
Author: skndstry, 2020-05-03 15:58:15