Как создать постоянную структуру ссылок с пользовательскими таксономиями и пользовательскими типами записей, такими как base-name / parent-tax / child-tax / custom-post-type-name

53

Я прочесываю этот сайт и 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 (только / basename / внучка-кошка / пост-имя / работы).

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

Джефф
источник

Ответы:

68

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

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

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

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

Джефф
источник
Исправлен - см. Вопрос. Джефф, спасибо за ваше объяснение! Но возможно ли будет опубликовать пользовательскую сборку posttype / taxonomy? Так я могу видеть, что я делаю не так ? Было бы очень благодарно!
Рейтц Бос
Привет, Джефф, спасибо за твой ответ! Я почти там, через 4 часа борюсь с этим. Моя единственная проблема заключается в том, что я получаю двойную косую черту перед названием сообщения (как это: портфолио / дисено-графика-2 / логотип // alquimia-sonora /). Вы можете мне помочь?
Cmorales
1
@Cmorales, Не уверен, не увидев свой код, но поищите место, где вы вручную определяете косую черту перед названием вашего сообщения, например, может быть регистрация clug или в функции filter_post_type? Если вы не можете отследить, где вы добавляете дополнительную косую черту, вы можете просто удалить последний символ из возвращенного значения функции get_taxonomy_parents, вызванной в filter_post_type_link, потому что это оставит вас с косой чертой, которая является первой из двойной. Удачи.
Джефф
1
«Если у вас будут разные уровни вложенных терминов, вам нужно написать функцию, чтобы проверить, является ли последний сегмент uri пользовательским типом записи или термином таксономии, чтобы узнать, какое правило добавить (спросите меня, если вам нужна помощь на этом) ... "Ну, вы можете мне помочь, пожалуйста? :)
Cmorales
2
^ это именно то, что мне было нужно. Кто-нибудь знает, как это сделать? см. мой вопрос здесь: wordpress.stackexchange.com/questions/102246/…
reikyoushin
2

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

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

vmassuchetto
источник
2
Этот плагин больше не доступен.
Энкоде