Статьи

Использование WordPress для создания системы FAQ с пользовательскими типами записей

Недавно я работал с моим клиентом, который работает профессиональным консультантом в своей области. Она спросила, могу ли я реализовать систему вопросов и ответов или страницу часто задаваемых вопросов, если быть точным. Я сказал: «Конечно, мы можем просто создать страницу и вставить туда вопросы и ответы с разным стилем», но она сказала, что создаст разные страницы и распределит вопросы и ответы по категориям, а для большей организованности ей нужна была другой подход.

Для этого я покажу вам, как я обрабатывал ее запросы с помощью простых строк кода с использованием пользовательских типов записей, таксономий и коротких кодов.

Что нам нужно, чтобы построить систему FAQ?

  • Нам нужны поля для вопросов и ответов.
  • Нам нужны категории для классификации и разделения различных типов вопросов и ответов на них.
  • В нашем случае нам нужен короткий код для встраивания этих групп вопросов или всех вопросов в страницу или сообщение.

Давайте начнем с создания пользовательского типа сообщения.

Естественно, мы собираемся начать с настройки пользовательского типа сообщения для наших вопросов и ответов. Мы собираемся создать новый пользовательский тип записи с помощью функции register_post_type() , но если вам нужен графический интерфейс для создания вашего типа записи, вы можете сгенерировать его с помощью инструмента GenerateWP Post Type Generator, как я делал в этом примере:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
 
if ( ! function_exists( ‘tuts_faq_cpt’ ) ) {
 
// register custom post type
    function tuts_faq_cpt() {
 
        // these are the labels in the admin interface, edit them as you like
        $labels = array(
            ‘name’ => _x( ‘FAQs’, ‘Post Type General Name’, ‘tuts_faq’ ),
            ‘singular_name’ => _x( ‘FAQ’, ‘Post Type Singular Name’, ‘tuts_faq’ ),
            ‘menu_name’ => __( ‘FAQ’, ‘tuts_faq’ ),
            ‘parent_item_colon’ => __( ‘Parent Item:’, ‘tuts_faq’ ),
            ‘all_items’ => __( ‘All Items’, ‘tuts_faq’ ),
            ‘view_item’ => __( ‘View Item’, ‘tuts_faq’ ),
            ‘add_new_item’ => __( ‘Add New FAQ Item’, ‘tuts_faq’ ),
            ‘add_new’ => __( ‘Add New’, ‘tuts_faq’ ),
            ‘edit_item’ => __( ‘Edit Item’, ‘tuts_faq’ ),
            ‘update_item’ => __( ‘Update Item’, ‘tuts_faq’ ),
            ‘search_items’ => __( ‘Search Item’, ‘tuts_faq’ ),
            ‘not_found’ => __( ‘Not found’, ‘tuts_faq’ ),
            ‘not_found_in_trash’ => __( ‘Not found in Trash’, ‘tuts_faq’ ),
        );
        $args = array(
            // use the labels above
            ‘labels’ => $labels,
            // we’ll only need the title, the Visual editor and the excerpt fields for our post type
            ‘supports’ => array( ‘title’, ‘editor’, ‘excerpt’, ),
            // we’re going to create this taxonomy in the next section, but we need to link our post type to it now
            ‘taxonomies’ => array( ‘tuts_faq_tax’ ),
            // make it public so we can see it in the admin panel and show it in the front-end
            ‘public’ => true,
            // show the menu item under the Pages item
            ‘menu_position’ => 20,
            // show archives, if you don’t need the shortcode
            ‘has_archive’ => true,
        );
        register_post_type( ‘tuts_faq’, $args );
 
    }
 
    // hook into the ‘init’ action
    add_action( ‘init’, ‘tuts_faq_cpt’, 0 );
 
}
 
?>

Совет: если ваш проект будет включать больше пользовательских типов записей, которые могут быть более сложными, чем этот простой тип записей FAQ, я могу предложить классный инструмент под названием SuperCPT, который позволяет создавать новые типы записей с еще более простым кодом. Я написал учебник по SuperCPT, вы можете проверить его здесь .

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

Основной функцией здесь является register_taxonomy() но, опять же, вы можете использовать инструмент GenerateWP Taxonomy Generator, если вам нужен графический интерфейс.

Вот код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
 
if ( ! function_exists( ‘tuts_faq_tax’ ) ) {
 
    // register custom taxonomy
    function tuts_faq_tax() {
 
        // again, labels for the admin panel
        $labels = array(
            ‘name’ => _x( ‘FAQ Categories’, ‘Taxonomy General Name’, ‘tuts_faq’ ),
            ‘singular_name’ => _x( ‘FAQ Category’, ‘Taxonomy Singular Name’, ‘tuts_faq’ ),
            ‘menu_name’ => __( ‘FAQ Categories’, ‘tuts_faq’ ),
            ‘all_items’ => __( ‘All FAQ Cats’, ‘tuts_faq’ ),
            ‘parent_item’ => __( ‘Parent FAQ Cat’, ‘tuts_faq’ ),
            ‘parent_item_colon’ => __( ‘Parent FAQ Cat:’, ‘tuts_faq’ ),
            ‘new_item_name’ => __( ‘New FAQ Cat’, ‘tuts_faq’ ),
            ‘add_new_item’ => __( ‘Add New FAQ Cat’, ‘tuts_faq’ ),
            ‘edit_item’ => __( ‘Edit FAQ Cat’, ‘tuts_faq’ ),
            ‘update_item’ => __( ‘Update FAQ Cat’, ‘tuts_faq’ ),
            ‘separate_items_with_commas’ => __( ‘Separate items with commas’, ‘tuts_faq’ ),
            ‘search_items’ => __( ‘Search Items’, ‘tuts_faq’ ),
            ‘add_or_remove_items’ => __( ‘Add or remove items’, ‘tuts_faq’ ),
            ‘choose_from_most_used’ => __( ‘Choose from the most used items’, ‘tuts_faq’ ),
            ‘not_found’ => __( ‘Not Found’, ‘tuts_faq’ ),
        );
        $args = array(
            // use the labels above
            ‘labels’ => $labels,
            // taxonomy should be hierarchial so we can display it like a category section
            ‘hierarchical’ => true,
            // again, make the taxonomy public (like the post type)
            ‘public’ => true,
        );
        // the contents of the array below specifies which post types should the taxonomy be linked to
        register_taxonomy( ‘tuts_faq_tax’, array( ‘tuts_faq’ ), $args );
 
    }
 
    // hook into the ‘init’ action
    add_action( ‘init’, ‘tuts_faq_tax’, 0 );
 
}
 
?>

Это оно! Теперь у вас есть тип поста FAQ с таксономией под названием «Категории FAQ», связанной друг с другом! Проверьте панель администрирования, и вы увидите пункт меню «FAQ категории» под «FAQ».

Как и обычные категории сообщений, вы можете добавлять, редактировать или удалять их на странице «Категории часто задаваемых вопросов» или добавлять новые категории во время написания нового раздела «Часто задаваемые вопросы».

Здесь начинается самое интересное: создание шорткода. (Если вы читали мои предыдущие посты, вы знаете, что я большой поклонник шорткодов WordPress.) Мы собираемся сделать элементы FAQ встраиваемыми в посты и страницы.

Вот что должно произойти:

  • запрос внутри нашего нового пользовательского типа сообщения,
  • фильтровать его категории с помощью параметра шорткода,
  • отображать вопросы и ответы в виде заголовков и контента,
  • показать отрывок ответа со ссылкой «Еще …», управляемой другим параметром шорткода.

Давайте начнем создавать шорткод. Как и в коде выше, я собираюсь добавить несколько полезных комментариев:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
 
if ( ! function_exists( ‘tuts_faq_shortcode’ ) ) {
 
    function tuts_faq_shortcode( $atts ) {
        extract( shortcode_atts(
                array(
                    // category slug attribute — defaults to blank
                    ‘category’ => »,
                    // full content or excerpt attribute — defaults to full content
                    ‘excerpt’ => ‘false’,
                ), $atts )
        );
         
        $output = »;
         
        // set the query arguments
        $query_args = array(
            // show all posts matching this query
            ‘posts_per_page’ => -1,
            // show the ‘tuts_faq’ custom post type
            ‘post_type’ => ‘tuts_faq’,
            // show the posts matching the slug of the FAQ category specified with the shortcode’s attribute
            ‘tax_query’ => array(
                array(
                    ‘taxonomy’ => ‘tuts_faq_tax’,
                    ‘field’ => ‘slug’,
                    ‘terms’ => $category,
                )
            ),
            // tell WordPress that it doesn’t need to count total rows — this little trick reduces load on the database if you don’t need pagination
            ‘no_found_rows’ => true,
        );
         
        // get the posts with our query arguments
        $faq_posts = get_posts( $query_args );
        $output .= ‘<div class=»tuts-faq»>’;
         
        // handle our custom loop
        foreach ( $faq_posts as $post ) {
            setup_postdata( $post );
            $faq_item_title = get_the_title( $post->ID );
            $faq_item_permalink = get_permalink( $post->ID );
            $faq_item_content = get_the_content();
            if( $excerpt == ‘true’ )
                $faq_item_content = get_the_excerpt() .
             
            $output .= ‘<div class=»tuts-faq-item»>’;
            $output .= ‘<h3 class=»tuts-faq-item-title»>’ .
            $output .= ‘<div class=»tuts-faq-item-content»>’ .
            $output .= ‘</div>’;
        }
         
        wp_reset_postdata();
         
        $output .= ‘</div>’;
         
        return $output;
    }
 
    add_shortcode( ‘faq’, ‘tuts_faq_shortcode’ );
 
}
 
?>

Это оно! Теперь у нас есть удобный шорткод для вставки наших вопросов и ответов. Вы можете tuts-faq его с помощью имен классов tuts-faq , tuts-faq-item , tuts-faq-item-title и tuts-faq-item-content . Хотя, это должно быть хорошо, даже если вы не включите дополнительный стиль.

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

Вот полный код:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<?php
/*
Plugin Name: Simple FAQ System
Plugin URI: http://code.tutsplus.com/
Description: Helps you create an FAQ section for your WordPress website.
Version: 1.0
Author: Barış Ünver
Author URI: http://hub.tutsplus.com/authors/baris-unver
License: Public Domain
*/
 
if ( ! function_exists( ‘tuts_faq_cpt’ ) ) {
 
// register custom post type
    function tuts_faq_cpt() {
 
        // these are the labels in the admin interface, edit them as you like
        $labels = array(
            ‘name’ => _x( ‘FAQs’, ‘Post Type General Name’, ‘tuts_faq’ ),
            ‘singular_name’ => _x( ‘FAQ’, ‘Post Type Singular Name’, ‘tuts_faq’ ),
            ‘menu_name’ => __( ‘FAQ’, ‘tuts_faq’ ),
            ‘parent_item_colon’ => __( ‘Parent Item:’, ‘tuts_faq’ ),
            ‘all_items’ => __( ‘All Items’, ‘tuts_faq’ ),
            ‘view_item’ => __( ‘View Item’, ‘tuts_faq’ ),
            ‘add_new_item’ => __( ‘Add New FAQ Item’, ‘tuts_faq’ ),
            ‘add_new’ => __( ‘Add New’, ‘tuts_faq’ ),
            ‘edit_item’ => __( ‘Edit Item’, ‘tuts_faq’ ),
            ‘update_item’ => __( ‘Update Item’, ‘tuts_faq’ ),
            ‘search_items’ => __( ‘Search Item’, ‘tuts_faq’ ),
            ‘not_found’ => __( ‘Not found’, ‘tuts_faq’ ),
            ‘not_found_in_trash’ => __( ‘Not found in Trash’, ‘tuts_faq’ ),
        );
        $args = array(
            // use the labels above
            ‘labels’ => $labels,
            // we’ll only need the title, the Visual editor and the excerpt fields for our post type
            ‘supports’ => array( ‘title’, ‘editor’, ‘excerpt’, ),
            // we’re going to create this taxonomy in the next section, but we need to link our post type to it now
            ‘taxonomies’ => array( ‘tuts_faq_tax’ ),
            // make it public so we can see it in the admin panel and show it in the front-end
            ‘public’ => true,
            // show the menu item under the Pages item
            ‘menu_position’ => 20,
            // show archives, if you don’t need the shortcode
            ‘has_archive’ => true,
        );
        register_post_type( ‘tuts_faq’, $args );
 
    }
 
    // hook into the ‘init’ action
    add_action( ‘init’, ‘tuts_faq_cpt’, 0 );
 
}
 
if ( ! function_exists( ‘tuts_faq_tax’ ) ) {
 
    // register custom taxonomy
    function tuts_faq_tax() {
 
        // again, labels for the admin panel
        $labels = array(
            ‘name’ => _x( ‘FAQ Categories’, ‘Taxonomy General Name’, ‘tuts_faq’ ),
            ‘singular_name’ => _x( ‘FAQ Category’, ‘Taxonomy Singular Name’, ‘tuts_faq’ ),
            ‘menu_name’ => __( ‘FAQ Categories’, ‘tuts_faq’ ),
            ‘all_items’ => __( ‘All FAQ Cats’, ‘tuts_faq’ ),
            ‘parent_item’ => __( ‘Parent FAQ Cat’, ‘tuts_faq’ ),
            ‘parent_item_colon’ => __( ‘Parent FAQ Cat:’, ‘tuts_faq’ ),
            ‘new_item_name’ => __( ‘New FAQ Cat’, ‘tuts_faq’ ),
            ‘add_new_item’ => __( ‘Add New FAQ Cat’, ‘tuts_faq’ ),
            ‘edit_item’ => __( ‘Edit FAQ Cat’, ‘tuts_faq’ ),
            ‘update_item’ => __( ‘Update FAQ Cat’, ‘tuts_faq’ ),
            ‘separate_items_with_commas’ => __( ‘Separate items with commas’, ‘tuts_faq’ ),
            ‘search_items’ => __( ‘Search Items’, ‘tuts_faq’ ),
            ‘add_or_remove_items’ => __( ‘Add or remove items’, ‘tuts_faq’ ),
            ‘choose_from_most_used’ => __( ‘Choose from the most used items’, ‘tuts_faq’ ),
            ‘not_found’ => __( ‘Not Found’, ‘tuts_faq’ ),
        );
        $args = array(
            // use the labels above
            ‘labels’ => $labels,
            // taxonomy should be hierarchial so we can display it like a category section
            ‘hierarchical’ => true,
            // again, make the taxonomy public (like the post type)
            ‘public’ => true,
        );
        // the contents of the array below specifies which post types should the taxonomy be linked to
        register_taxonomy( ‘tuts_faq_tax’, array( ‘tuts_faq’ ), $args );
 
    }
 
    // hook into the ‘init’ action
    add_action( ‘init’, ‘tuts_faq_tax’, 0 );
 
}
 
if ( ! function_exists( ‘tuts_faq_shortcode’ ) ) {
 
    function tuts_faq_shortcode( $atts ) {
        extract( shortcode_atts(
                array(
                    // category slug attribute — defaults to blank
                    ‘category’ => »,
                    // full content or excerpt attribute — defaults to full content
                    ‘excerpt’ => ‘false’,
                ), $atts )
        );
         
        $output = »;
         
        // set the query arguments
        $query_args = array(
            // show all posts matching this query
            ‘posts_per_page’ => -1,
            // show the ‘tuts_faq’ custom post type
            ‘post_type’ => ‘tuts_faq’,
            // show the posts matching the slug of the FAQ category specified with the shortcode’s attribute
            ‘tax_query’ => array(
                array(
                    ‘taxonomy’ => ‘tuts_faq_tax’,
                    ‘field’ => ‘slug’,
                    ‘terms’ => $category,
                )
            ),
            // tell WordPress that it doesn’t need to count total rows — this little trick reduces load on the database if you don’t need pagination
            ‘no_found_rows’ => true,
        );
         
        // get the posts with our query arguments
        $faq_posts = get_posts( $query_args );
        $output .= ‘<div class=»tuts-faq»>’;
         
        // handle our custom loop
        foreach ( $faq_posts as $post ) {
            setup_postdata( $post );
            $faq_item_title = get_the_title( $post->ID );
            $faq_item_permalink = get_permalink( $post->ID );
            $faq_item_content = get_the_content();
            if( $excerpt == ‘true’ )
                $faq_item_content = get_the_excerpt() .
             
            $output .= ‘<div class=»tuts-faq-item»>’;
            $output .= ‘<h2 class=»faq-item-title»>’ .
            $output .= ‘<div class=»faq-item-content»>’ .
            $output .= ‘</div>’;
        }
         
        wp_reset_postdata();
         
        $output .= ‘</div>’;
         
        return $output;
    }
 
    add_shortcode( ‘faq’, ‘tuts_faq_shortcode’ );
 
}
 
function tuts_faq_activate() {
    tuts_faq_cpt();
    flush_rewrite_rules();
}
 
register_activation_hook( __FILE__, ‘tuts_faq_activate’ );
 
function tuts_faq_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, ‘tuts_faq_deactivate’ );
 
?>

Моя клиентка была довольна результатами, когда я показал ей, как ее использовать. Но здесь мы можем расширить код с большей функциональностью, например …

  1. Эффект аккордеона: Если вы хотите сделать разделы часто задаваемых вопросов более привлекательными с помощью некоторых эффектов переключения, вы можете использовать несколько потрясающих плагинов jQuery. Если вы хотите использовать jQuery UI, есть замечательное руководство от Шейна Осборна, в котором показано, как это сделать.
  2. Разбиение на страницы: если у вас есть много вопросов и ответов для категории и вы не хотите отображать все элементы сразу, вы можете ограничить количество сообщений, изменив параметр posts_per_page в пользовательском запросе нашего шорткода и добавив требуемый код для пагинационных ссылок ниже строки с wp_reset_postdata(); код. Не забудьте удалить 'no_found_rows' => true, хотя — разбиение на страницы не будет работать, если вы не удалите это!
  3. Случайный вопрос: допустим, вы хотите отобразить один случайный вопрос и ответ на главной странице, и вы хотите, чтобы он обновлялся при каждом обновлении страницы. Все, что вам нужно сделать, это перейти к пользовательскому запросу, изменить параметр posts_per_page с -1 на 1 и добавить еще одну строку с кодом 'orderby' => 'random', и все готово!

Это то, как вы строите простую систему часто задаваемых вопросов в WordPress с помощью пользовательских типов сообщений, пользовательских таксономий и шорткодов. Надеюсь, вам понравился этот урок, и вы сможете использовать его в своем следующем проекте. Не забудьте поделиться статьей, если она вам понравилась!

У вас есть идеи по улучшению этой системы FAQ? Поделитесь своими комментариями ниже!