Индекс на базата ( http://example.com/faq/
) [Индекс на цялата база]
- Основна категория (
http://example.com/faq/category/
) [Индекс на Основната категория]- Публикация в основната категория (
http://example.com/faq/category/post-1-slug/
) [Преглед на Публикация 1] - Под-категория (
http://example.com/faq/category/sub-category/
) [Индекс на под-категорията]- Публикация в под-категорията (
http://example.com/faq/category/sub-category/post-2-slug/
) [Преглед на Публикация 2]
- Публикация в под-категорията (
- Публикация в основната категория (
- Друга основна категория (
http://example.com/faq/another-category/
) [Индекс на другата основна категория]
Всичко изглежда нормално(като структура на линковете) за нормалния потребител, обаче WordPress е на друго мнение по въпроса Вместо линк като http://example.com/faq/category/
ние ще можем да видим индекса на основната категория на линк от рода на http://example.com/faq-category/category/
. Което както виждате не съвпада съвсем с първоначалната идея. За да оправим този проблем трябва да прибегнем до добавянето на няколко специално написани Permalink правила и функции.
Първата стъпка е да регистрираме новия пост тип(Custom Post Type). Това се случва със следната функция:
<?php add_action( 'init', 'register_faq_post_type' ); function register_faq_post_type() { register_post_type( 'faq', array( 'labels' => array( 'name' => 'Frequently Asked Questions', 'menu_name' => 'FAQ Manager', 'singular_name' => 'Question', 'all_items' => 'All Questions' ), 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'menu_position ' => 20, 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'comments', 'post-formats', 'revisions' ), 'hierarchical' => false, 'has_archive' => 'faq', 'rewrite' => array( 'slug' => 'faq-item', 'hierarchical' => true, 'with_front' => false ) ) ); register_taxonomy( 'faq-category', array( 'faq' ), array( 'labels' => array( 'name' => 'FAQ Categories', 'menu_name' => 'FAQ Categories', 'singular_name' => 'FAQ Category', 'all_items' => 'All Categories' ), 'public' => true, 'hierarchical' => true, 'show_ui' => true, 'rewrite' => array( 'slug' => 'faq-category', 'hierarchical' => true, 'with_front' => false ), ) ); } ?>
Този код ще регистрира новия пост тип, заедно с новата таксономия „FAQ Categories“, която ще използваме за да категоризираме въпросите.
След като регистрираме новия пост тип остава да добавим две функции които да направят така че Permalink-овете да работят както искаме ние
<?php add_action( 'generate_rewrite_rules', 'register_faq_rewrite_rules' ); function register_faq_rewrite_rules( $wp_rewrite ) { $new_rules = array( 'faq/([^/]+)/?$' => 'index.php?faq-category=' . $wp_rewrite->preg_index( 1 ), 'faq/([^/]+)/([^/]+)/?$' => 'index.php?post_type=faq&faq-category=' . $wp_rewrite->preg_index( 1 ) . '&faq=' . $wp_rewrite->preg_index( 2 ), 'faq/([^/]+)/([^/]+)/page/(\d{1,})/?$' => 'index.php?post_type=faq&faq-category=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 3 ), 'faq/([^/]+)/([^/]+)/([^/]+)/?$' => 'index.php?post_type=faq&faq-category=' . $wp_rewrite->preg_index( 2 ) . '&faq=' . $wp_rewrite->preg_index( 3 ), ); $wp_rewrite->rules = $new_rules + $wp_rewrite->rules; } // A hacky way of adding support for flexible custom permalinks // There is one case in which the rewrite rules from register_kb_rewrite_rules() fail: // When you visit the archive page for a child section(for example: http://example.com/faq/category/child-category) // The deal is that in this situation, the URL is parsed as a Knowledgebase post with slug "child-category" from the "category" section function fix_faq_subcategory_query($query) { if ( isset( $query['post_type'] ) && 'faq' == $query['post_type'] ) { if ( isset( $query['faq'] ) && $query['faq'] && isset( $query['faq-category'] ) && $query['faq-category'] ) { $query_old = $query; // Check if this is a paginated result(like search results) if ( 'page' == $query['faq-category'] ) { $query['paged'] = $query['name']; unset( $query['faq-category'], $query['name'], $query['faq'] ); } // Make it easier on the DB $query['fields'] = 'ids'; $query['posts_per_page'] = 1; // See if we have results or not $_query = new WP_Query( $query ); if ( ! $_query->posts ) { $query = array( 'faq-category' => $query['faq'] ); if ( isset( $query_old['faq-category'] ) && 'page' == $query_old['faq-category'] ) { $query['paged'] = $query_old['name']; } } } } return $query; } add_filter( 'request', 'fix_faq_subcategory_query', 10 ); ?>
В горния код регистрираме две функции – register_faq_rewrite_rules()
и fix_faq_subcategory_query()
.
Първата функция добавя следните няколко правила:
faq/([^/]+)/?$
– това правило ще бъде приложено когато адреса на страницата която се зарежда прилича на „faq/any-character/“ – тоест когато имаме начална част „faq/“ последвана от всякаква комбинация от символи, без „/“( „([^/]+)“ ), евентуално последвана от „/“( „/?“ ). Също така тази част трябва да е последната част от адреса на страницата, за да има съвпадение(т.е. няма да има съвпадение, ако адреса е „faq/any-character/something“).Когато адреса съвпадне, на текущата страница ще бъде показан архив за категорията(според примера който дадох по-горе) „any-character“.faq/([^/]+)/([^/]+)/?$
– това правило е почти същото като предишното, с изключение на това че вече адреса който би съвпаднал би изглеждал като „faq/any-character/post-slug/“.Това ще зареди публикация с кратко име(slug) „post-slug“ от категорията за ЧЗВ с кратко име „any-character“.faq/([^/]+)/([^/]+)/([^/]+)/?$
– това правило е почти същото като предишното, с изключение на това че вече адреса който би съвпаднал би изглеждал като „faq/any-character/sub-category/post-slug/“.Това ще зареди публикация с кратко име(slug) „post-slug“ от категорията за ЧЗВ с кратко име „sub-category“.
Втората функция от друга страна оправя проблема със под-категориите. А самият проблем се състои в това, че когато се опитате да заредите страница с адрес faq/category/child-category/
, WordPress ще се опита да зареди публикация с кратко име „child-category“ вместо под-категорията с кратко име „child-category“. Самата функция е по всяка вероятност не най-красивото решение на проблема, най-малкото защото трябва да направим една допълнителна заявка към базата данни, но това е единствения начин по който успях да реша проблема Понеже функцията проверява дали има публикации с краткото име „child-category“, ако случайно има такава публикация, може да получите неочаквани резултати
Това е достатъчно за да подкарате секцията за ЧЗВ, обаче в момента ако искате да използвате пълноценно новите адреси на категориите и публикациите, ще трябва да си ги пишете сами. Това е защото WordPress не знае как трябва да генерира линковете така че да съвпадат с нашата идея. За това добавяме още няколко функции:
<?php function faq_article_permalink( $article_id, $section_id = false, $leavename = false, $only_permalink = false ) { $taxonomy = 'faq-category'; $article = get_post( $article_id ); $return = '<a href="'; $permalink = ( $section_id ) ? trailingslashit( get_term_link( intval( $section_id ), 'faq-category' ) ) : home_url( '/faq/' ); $permalink .= trailingslashit( ( $leavename ? "%$article->post_type%" : $article->post_name ) ); $return .= $permalink . '/" >' . get_the_title( $article->ID ) . '</a>'; return ( $only_permalink ) ? $permalink : $return; } function filter_faq_post_link( $permalink, $post, $leavename ) { if ( get_post_type( $post->ID ) == 'faq' ) { $terms = wp_get_post_terms( $post->ID, 'faq-category' ); $term = ( $terms ) ? $terms[0]->term_id : false; $permalink = faq_article_permalink( $post->ID, $term, $leavename, true ); } return $permalink; } add_filter( 'post_type_link', 'filter_faq_post_link', 100, 3 ); function filter_faq_section_terms_link( $termlink, $term, $taxonomy = false ) { if ( $taxonomy == 'faq-category' ) { $section_ancestors = get_ancestors( $term->term_id, $taxonomy ); krsort( $section_ancestors ); $termlink = home_url( '/faq/' ); foreach ( $section_ancestors as $ancestor ) { $section_ancestor = get_term( $ancestor, $taxonomy ); $termlink .= $section_ancestor->slug . '/'; } $termlink .= trailingslashit( $term->slug ); } return $termlink; } add_filter( 'term_link', 'filter_faq_section_terms_link', 100, 3 ); ?>
Горните функции „филтрират“ резултата от две вградени в WordPress функции, които се грижат да създадат правилните линкове за всички страници, публикации и архиви на таксономии.
Остава един проблем, който може да не е никак малък за някои потребители – проблема с дубликиращото се съдържание. Има доста голяма вероятност Google или някоя друга търсачка която обхожда сайта ви да не остане очарована от факта, че намира идентично съдържание на два различни адреса(например faq-item/post-2-slug/
и faq/category/sub-category/post-2-slug/
). Това може да се избегне с една функция която да препраща потребителите към правилния адрес, но оставям това на вас.
Източник: http://themoonwatch.com/bg/%D0%BA%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F/php-i-wordpress/#sthash.GBKCWoNy.dpuf