Статьи

Создание виджета с вкладками для пользовательских типов записей

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


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

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

Есть только три файла, которые вам нужно изменить, чтобы добавить эту функцию в вашу тему, и все они являются стандартными файлами, которые поставляются практически со всеми темами WP:

  1. functions.php
  2. header.php
  3. style.css

В этом уроке я буду использовать стандартную тему WP 3.0 под названием TwentyTen, но метод будет одинаковым для любой темы, которую вы хотите изменить — вы все равно будете редактировать (или создавать, если они не существуют) эти три файла, независимо от того, какую тему вы модифицируете / создаете. Пользовательские типы постов, которые я буду создавать, — это обзоры фильмов, обзоры музыки и обзоры игр:


Прежде чем мы создадим виджет, который будет отображать наши обзоры, мы должны сначала создать сами обзоры, и для этого нам нужно создать три новых пользовательских типа записей. В этом руководстве предполагается, что вы знакомы с созданием пользовательских типов записей, поэтому, если вам нужно разобраться с этим, прежде чем продолжить, Кодекс подробно объясняет, как регистрировать новые типы записей. Теперь мы создадим наш тип записи Обзоры фильмов. Откройте файл functions.php и добавьте следующий код в конце:

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
//##########################################
//create custom post type of Movie Reviews
//##########################################
 
function create_oswc_movie_reviews() {
    register_post_type( ‘oswc_movie_reviews’,
        array(
            ‘labels’ => array(
                ‘name’ => __( ‘Movie Reviews’ , ‘twentyten’),
                ‘singular_name’ => __( ‘Movie Review’ , ‘twentyten’),
                ‘add_new’ => __(‘Add new review’, ‘twentyten’),
                ‘edit_item’ => __(‘Edit review’, ‘twentyten’),
                ‘new_item’ => __(‘New review’, ‘twentyten’),
                ‘view_item’ => __(‘View review’, ‘twentyten’),
                ‘search_items’ => __(‘Search reviews’, ‘twentyten’),
                ‘not_found’ => __(‘No reviews found’, ‘twentyten’),
                ‘not_found_in_trash’ => __(‘No reviews found in Trash’, ‘twentyten’)
            ),
            ‘public’ => true,
            ‘menu_position’ => 25,
            ‘rewrite’ => array(‘slug’ => ‘movie-review’),
            ‘supports’ => array(‘title’,’editor’,’author’,’thumbnail’,’excerpt’,’trackbacks’,’custom-fields’,’comments’,’revisions’),
            ‘taxonomies’ => array(‘category’, ‘post_tag’)
        )
    );
}
add_action( ‘init’, ‘create_oswc_movie_reviews’ );

Это создает тип записи с именем oswc_movie_reviews, сообщает WP, какими должны быть все метки типа записи, делает тип записи общедоступным, помещает его сразу после меню «Комментарии» в структуре меню администратора WP, переписывает слаг типа записи (более симпатично). в постоянных ссылках), сообщает WP, что нужно включить определенные атрибуты для типа записи (например, миниатюру и выдержку), и, наконец, сообщает WP, чтобы пользователь мог назначать категории и теги для типа записи, как обычные записи.

Для краткости мы не будем определять какие-либо пользовательские таксономии, поскольку создаваемый нами виджет никак не взаимодействует с таксономиями. В реальной ситуации вы, скорее всего, создадите такие нестандартные таксономии, как Movie Genre, Movie Director, Actors и т. Д. Чтобы узнать, как создавать собственные таксономии, обратитесь к Кодексу WordPress, связанному с выше.

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

Далее, давайте создадим два других пользовательских типа записей, которые мы будем использовать в этом виджете. Логика точно такая же, как у только что добавленного типа «Обзоры фильмов». Все, что мы делаем, это изменяем код, чтобы отразить Music Reviews и Game Reviews, соответственно. Добавьте этот код после кода, который вы добавили выше:

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
//##########################################
//create custom post type of Music Reviews
//##########################################
 
function create_oswc_music_reviews() {
    register_post_type( ‘oswc_music_reviews’,
        array(
            ‘labels’ => array(
                ‘name’ => __( ‘Music Reviews’, ‘twentyten’ ),
                ‘singular_name’ => __( ‘Music Review’, ‘twentyten’ ),
                ‘add_new’ => __(‘Add new review’, ‘twentyten’),
                ‘edit_item’ => __(‘Edit review’, ‘twentyten’),
                ‘new_item’ => __(‘New review’, ‘twentyten’),
                ‘view_item’ => __(‘View review’, ‘twentyten’),
                ‘search_items’ => __(‘Search reviews’, ‘twentyten’),
                ‘not_found’ => __(‘No reviews found’, ‘twentyten’),
                ‘not_found_in_trash’ => __(‘No reviews found in Trash’, ‘twentyten’)
            ),
            ‘public’ => true,
            ‘menu_position’ => 26,
            ‘rewrite’ => array(‘slug’ => ‘music-review’),
            ‘supports’ => array(‘title’,’editor’,’author’,’thumbnail’,’excerpt’,’trackbacks’,’custom-fields’,’comments’,’revisions’),
            ‘taxonomies’ => array(‘category’, ‘post_tag’)
        )
    );
}
add_action( ‘init’, ‘create_oswc_music_reviews’ );
 
//##########################################
//create custom post type of Game Reviews
//##########################################
 
function create_oswc_game_reviews() {
    register_post_type( ‘oswc_game_reviews’,
        array(
            ‘labels’ => array(
                ‘name’ => __( ‘Game Reviews’, ‘twentyten’ ),
                ‘singular_name’ => __( ‘Game Review’, ‘twentyten’ ),
                ‘add_new’ => __(‘Add new review’, ‘twentyten’),
                ‘edit_item’ => __(‘Edit review’, ‘twentyten’),
                ‘new_item’ => __(‘New review’, ‘twentyten’),
                ‘view_item’ => __(‘View review’, ‘twentyten’),
                ‘search_items’ => __(‘Search reviews’, ‘twentyten’),
                ‘not_found’ => __(‘No reviews found’, ‘twentyten’),
                ‘not_found_in_trash’ => __(‘No reviews found in Trash’, ‘twentyten’)
            ),
            ‘public’ => true,
            ‘menu_position’ => 27,
            ‘rewrite’ => array(‘slug’ => ‘game-review’),
            ‘supports’ => array(‘title’,’editor’,’author’,’thumbnail’,’excerpt’,’trackbacks’,’custom-fields’,’comments’,’revisions’),
            ‘taxonomies’ => array(‘category’, ‘post_tag’)
        )
    );
}
add_action( ‘init’, ‘create_oswc_game_reviews’ );

Загрузите измененный файл functions.php, и вы увидите элементы меню для всех трех пользовательских типов записей. Ваша админ панель должна выглядеть так:


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

Итак, что нам нужно сделать, чтобы у обзора был звездный рейтинг, который отображается в виджете? Просто: добавьте настраиваемое поле. Во-первых, убедитесь, что на панели инструментов «Параметры экрана» включена панель «Пользовательские поля», переключив вкладку «Параметры экрана» и выбрав «Пользовательские поля»:

Когда видимые пользовательские поля видны, добавьте новое пользовательское поле с именем Rating . Присвойте ему числовое значение от 0 до 5, увеличивая на 0,5. Таким образом, доступные значения будут 0, 0,5, 1, 1,5, 2, 2,5, 3, 3,5, 4, 4,5, 5.

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

Точно так же добавьте рецензии для двух других типов рецензий. Добавьте хотя бы несколько отзывов для каждого из трех типов, чтобы виджету было что отображать. С нашим контентом на месте, теперь мы готовы создать виджет, который будет отображать наши отзывы. Мы будем атаковать виджет в три этапа: PHP, затем jQuery и, наконец, CSS.


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

Есть четыре функции, которые мы должны добавить при расширении класса WP_Widget, чтобы добавить наш виджет. Вот структура кода, который мы будем использовать для расширения класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
class My_Widget extends WP_Widget {
    function My_Widget() {
        // widget actual processes
    }
 
    function widget($args, $instance) {
        // outputs the content of the widget
    }
 
    function update($new_instance, $old_instance) {
        // processes widget options to be saved
    }
     
    function form($instance) {
        // outputs the options form on admin
    }
}
register_widget(‘My_Widget’);

Как видите, нам нужна функция, которая присваивает имена и создает виджет, функция, которая управляет тем, как он отображается на внешнем интерфейсе, функция, которая управляет обновлением параметров виджета, и функция, которая управляет тем, как он отображается на панели администратора ( WordPress >> Внешний вид >> Страница виджетов). После того как мы сделаем все это, мы зарегистрируем виджет в WordPress.

Для получения подробной информации о разработке виджетов см. Кодекс , который дополнительно объясняет API виджетов WordPress.

Давайте создадим каждую функцию и сделаем все уникальным для нашего пользовательского виджета. Сначала мы заключаем все это в класс с именем нашего виджета:

1
2
3
class oswc_tabbed_latest_reviews extends WP_Widget {
    // …widget functions…
}

Затем мы добавляем первую функцию внутри этого класса. Эта функция имеет то же имя, что и класс, который является именем нашего виджета. Мы будем настраивать красивое имя нашего виджета, которое будет отображаться на странице виджетов, а также некоторые настройки по умолчанию для виджета:

1
2
3
4
5
6
7
8
function oswc_tabbed_latest_reviews() {
    // widget settings
    $widget_ops = array( ‘classname’ => ‘Latest Review Tabs’, ‘description’ => ‘Displays reviews by most recent or highest rated in a jQuery tabbed format.’ );
    // widget control settings
    $control_ops = array( ‘width’ => 250, ‘height’ => 350, ‘id_base’ => ‘oswc_tabbed_latest_reviews’ );
    // create the widget
    $this->WP_Widget( ‘oswc_tabbed_latest_reviews’, ‘Latest Review Tabs’, $widget_ops, $control_ops );
}

Теперь давайте добавим следующую функцию. Сначала мы берем переменные из нашего виджета (который мы настроим в следующей функции), а затем создаем переменную, чтобы увидеть, как мы сортируем виджет:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
function widget( $args, $instance ) {
     
    extract( $args );
 
    /* User-selected settings.
    $sort = $instance[‘sort’];
    $showmovies = $instance[‘showmovies’];
    $showmusic = $instance[‘showmusic’];
    $showgames = $instance[‘showgames’];
    $nummovies = $instance[‘nummovies’];
    $nummusic = $instance[‘nummusic’];
    $numgames = $instance[‘numgames’];
     
    if($sort==»highest-rated») {
        $feedsort=»meta_value»;
        $metakey=»&meta_key=Rating»;
    } else {
        $feedsort=»date»;
        $metakey=»»;
    }

Затем мы начинаем создавать HTML. Оберните весь виджет в div с идентификатором «tabbed-reviews» (jQuery подключится к этому позже), а затем настройте вкладку для каждого типа обзора. Наконец, другой div оборачивает содержимое каждой вкладки:

01
02
03
04
05
06
07
08
09
10
11
/* HTML output */
?>
     
<div id=»tabbed-reviews»>
    <ul class=»tabnav»>
        <?php if($showmovies) { ?><li><a href=»#tabs-movies»>Movies</a></li><?php } ?>
        <?php if($showmusic) { ?><li><a href=»#tabs-music»>Music</a></li><?php } ?>
        <?php if($showgames) { ?><li><a href=»#tabs-games»>Games</a></li><?php } ?>
    </ul>
     
    <div class=»tabdiv-wrapper»>

Внутри элемента div tab-wrapper нам нужно создать цикл, который будет извлекать заголовки постов и звездные рейтинги из указанного пользовательского типа поста. Первая вкладка предназначена для обзоров фильмов, поэтому мы проверяем, отображается ли этот тип обзора в параметрах виджета, и если да, то отображаем вкладку с неупорядоченным списком внутри нее. Вот полный блок кода для содержимого вкладки «Обзор фильма», который мы выделим ниже:

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
<?php if($showmovies) { ?>
                     
    <div id=»tabs-movies» class=»tabdiv»>
        <ul>
            <?php // setup the query
            $args=’&suppress_filters=true&posts_per_page=’.$nummovies.’&post_type=oswc_movie_reviews&order=DESC&orderby=’.$feedsort.$metakey;
            $cust_loop = new WP_Query($args);
            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                // if we’re sorting by rating and this item does not have a rating, hide it
                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                    ?>
                    <li>
                         
                        <?php oswc_show_rating($rating);
                         
                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                         
                    </li>
                     
                <?php } ?>
                 
            <?php endwhile;
            endif;
            wp_reset_query();
             
            <li class=»last gentesque tooltip» title=»View all movie reviews»><a href=»movie-reviews/»>More</a></li>
 
        </ul>
    </div>
     
<?php } ?>

Сердцем этого блока кода является пользовательский цикл, который мы создаем для получения постов из типа постов «Обзоры фильмов». Вот аргументы, которые мы используем для цикла:

1
$args=’&suppress_filters=true&posts_per_page=’.$nummovies.’&post_type=oswc_movie_reviews&order=DESC&orderby=’.$feedsort.$metakey;

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

Самая важная часть — это post_type = oswc_movie_reviews, так как это говорит этому циклу искать только тот тип поста, который мы создали выше. Наконец, мы просто подключаем наши параметры виджета для количества сообщений и сортировки.

Чтобы получить наши звезды, мы берем значение пользовательского поля, которое мы добавили к обзору:

1
$rating = get_post_meta(get_the_ID(), «Rating», $single = true);

И затем мы передаем это значение функции, которую еще не создали:

1
<?php oswc_show_rating($rating);

После цикла мы включаем ссылку Подробнее. Поместите URL-адрес на определенную страницу пользовательского типа для ссылки href (создание этой страницы выходит за рамки данного руководства).

1
<li class=»last gentesque tooltip» title=»View all movie reviews»><a href=»movie-reviews/»>More</a></li>

Теперь нам нужно сделать то же самое для Обзоров музыки и Обзоров игр. Вот полный блок кода для обоих типов обзора:

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($showmusic) { ?>
                     
    <div id=»tabs-music» class=»tabdiv»>
        <ul>
            <?php // setup the query
            $args=’&suppress_filters=true&posts_per_page=’.$nummusic.’&post_type=oswc_music_reviews&order=DESC&orderby=’.$feedsort.$metakey;
            $cust_loop = new WP_Query($args);
            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                // if we’re sorting by rating and this item does not have a rating, hide it
                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                    ?>
                    <li>
                         
                        <?php oswc_show_rating($rating);
                         
                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                         
                    </li>
                     
                <?php } ?>
                 
            <?php endwhile;
            endif;
            wp_reset_query();
             
            <li class=»last gentesque tooltip» title=»View all music reviews»><a href=»music-reviews/»>More</a></li>
 
        </ul>
    </div>
     
<?php } ?>
 
<?php if($showgames) { ?>
     
    <div id=»tabs-games» class=»tabdiv»>
        <ul>
            <?php // setup the query
            $args=’&suppress_filters=true&posts_per_page=’.$numgames.’&post_type=oswc_game_reviews&order=DESC&orderby=’.$feedsort.$metakey;
            $cust_loop = new WP_Query($args);
            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                // if we’re sorting by rating and this item does not have a rating, hide it
                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                    ?>
                    <li>
                         
                        <?php oswc_show_rating($rating);
                         
                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                         
                    </li>
                     
                <?php } ?>
                 
            <?php endwhile;
            endif;
            wp_reset_query();
             
            <li class=»last gentesque tooltip» title=»View all video game reviews»><a href=»game-reviews/»>More</a></li>
 
        </ul>
    </div>
     
<?php } ?>

Не забудьте закрыть теги div, которые мы использовали в начале нашего виджета HTML, и закрыть функцию PHP!

1
2
3
4
5
6
        </div>
                                  
    </div>
     
<?php
}

Наша третья функция внутри класса WP_Widget — это функция обновления. Все, что делает эта функция — получает старые и новые опции из виджета при нажатии кнопки «Сохранить» и соответствующим образом обновляет массив настроек виджета:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
     
    $sort = $instance[‘sort’];
    $showmovies = $instance[‘showmovies’];
    $showmusic = $instance[‘showmusic’];
    $showgames = $instance[‘showgames’];
    $nummovies = $instance[‘nummovies’];
    $nummusic = $instance[‘nummusic’];
    $numgames = $instance[‘numgames’];
 
    /* Strip tags (if needed) and update the widget settings.
    $instance[‘sort’] = strip_tags( $new_instance[‘sort’] );
    $instance[‘showmovies’] = isset( $new_instance[‘showmovies’] );
    $instance[‘showmusic’] = isset( $new_instance[‘showmusic’] );
    $instance[‘showgames’] = isset( $new_instance[‘showgames’] );
    $instance[‘nummovies’] = strip_tags( $new_instance[‘nummovies’] );
    $instance[‘nummusic’] = strip_tags( $new_instance[‘nummusic’] );
    $instance[‘numgames’] = strip_tags( $new_instance[‘numgames’] );
 
    return $instance;
}

Наша четвертая и последняя функция для создания нашего виджета устанавливает, как наш виджет будет отображаться на странице администратора. Вы заметите, что поле формы создается для каждой опции, с которой нам нужно иметь дело. Этот код позволит виджету предлагать следующие 7 вариантов:

  1. Как отсортировать посты
  2. Отображать или нет вкладку «Обзоры фильмов»
  3. Сколько обзоров фильмов для отображения
  4. Отображать или нет вкладку Music Reviews
  5. Сколько музыкальных обзоров для отображения
  6. Показывать или нет вкладку «Обзоры игр»
  7. Сколько обзоров игр отображать

Вот код, который устанавливает параметры администратора нашего виджета:

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
    function form( $instance ) {
 
        /* Set up some default widget settings.
        $defaults = array( ‘sort’ => ‘latest’, ‘showmovies’ => true, ‘showmusic’ => true, ‘showgames’ => true, ‘nummovies’ => 10, ‘nummusic’ => 10, ‘numgames’ => 10 );
        $instance = wp_parse_args( (array) $instance, $defaults );
         
        <p>
            <input class=»radio» type=»radio» <?php if($instance[‘sort’]==’highest-rated’) { ?>checked <?php } ?>name=»<?php echo $this->get_field_name( ‘sort’ ); ?>» value=»highest-rated» />
            Order reviews by highest rated<br />
            <input class=»radio» type=»radio» <?php if($instance[‘sort’]!=’highest-rated’) { ?>checked <?php } ?>name=»<?php echo $this->get_field_name( ‘sort’ ); ?>» value=»latest» />
            Order reviews by latest
        </p>
     
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showmovies’]) ? $instance[‘showmovies’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘nummovies’ ); ?>» name=»<?php echo $this->get_field_name( ‘nummovies’ ); ?>» value=»<?php echo $instance[‘nummovies’]; ?>» style=»width:30px» />
            movie reviews
             
        </p>
 
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showmusic’]) ? $instance[‘showmusic’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘nummusic’ ); ?>» name=»<?php echo $this->get_field_name( ‘nummusic’ ); ?>» value=»<?php echo $instance[‘nummusic’]; ?>» style=»width:30px» />
            music reviews
             
        </p>
 
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showgames’]) ? $instance[‘showgames’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘numgames’ ); ?>» name=»<?php echo $this->get_field_name( ‘numgames’ ); ?>» value=»<?php echo $instance[‘numgames’]; ?>» style=»width:30px» />
            game reviews
             
        </p>
         
        <?php
    }
}

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

1
2
3
4
5
6
//LOAD THE WIDGET
add_action(«widgets_init», «oswc_load_widgets»);
function oswc_load_widgets()
{
    register_widget(‘oswc_tabbed_latest_reviews’);
}

Вот полный блок кода, который используется для создания виджета для вашего удобства:

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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
//BUILD THE WIDGET
class oswc_tabbed_latest_reviews extends WP_Widget {
    function oswc_tabbed_latest_reviews() {
        // widget settings
        $widget_ops = array( ‘classname’ => ‘Latest Review Tabs’, ‘description’ => ‘Displays reviews by most recent or highest rated in a jQuery tabbed format.’ );
        // widget control settings
        $control_ops = array( ‘width’ => 250, ‘height’ => 350, ‘id_base’ => ‘oswc_tabbed_latest_reviews’ );
        // create the widget
        $this->WP_Widget( ‘oswc_tabbed_latest_reviews’, ‘Latest Review Tabs’, $widget_ops, $control_ops );
    }
    function widget( $args, $instance ) {
         
        extract( $args );
 
        /* User-selected settings.
        $sort = $instance[‘sort’];
        $showmovies = $instance[‘showmovies’];
        $showmusic = $instance[‘showmusic’];
        $showgames = $instance[‘showgames’];
        $nummovies = $instance[‘nummovies’];
        $nummusic = $instance[‘nummusic’];
        $numgames = $instance[‘numgames’];
         
        if($sort==»highest-rated») {
            $feedsort=»meta_value»;
            $metakey=»&meta_key=Rating»;
        } else {
            $feedsort=»date»;
            $metakey=»»;
        }
         
        /* HTML output */
        ?>
             
        <div id=»tabbed-reviews»>
            <ul class=»tabnav»>
                <?php if($showmovies) { ?><li><a href=»#tabs-movies»>Movies</a></li><?php } ?>
                <?php if($showmusic) { ?><li><a href=»#tabs-music»>Music</a></li><?php } ?>
                <?php if($showgames) { ?><li><a href=»#tabs-games»>Games</a></li><?php } ?>
            </ul>
             
            <div class=»tabdiv-wrapper»>
         
                <?php if($showmovies) { ?>
                     
                    <div id=»tabs-movies» class=»tabdiv»>
                        <ul>
                            <?php // setup the query
                            $args=’&suppress_filters=true&posts_per_page=’.$nummovies.’&post_type=oswc_movie_reviews&order=DESC&orderby=’.$feedsort.$metakey;
                            $cust_loop = new WP_Query($args);
                            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                                // if we’re sorting by rating and this item does not have a rating, hide it
                                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                                    ?>
                                    <li>
                                         
                                        <?php oswc_show_rating($rating);
                                         
                                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                                         
                                    </li>
                                     
                                <?php } ?>
                                 
                            <?php endwhile;
                            endif;
                            wp_reset_query();
                             
                            <li class=»last gentesque tooltip» title=»View all movie reviews»><a href=»movie-reviews/»>More</a></li>
        
                        </ul>
                    </div>
                     
                <?php } ?>
                 
                <?php if($showmusic) { ?>
                     
                    <div id=»tabs-music» class=»tabdiv»>
                        <ul>
                            <?php // setup the query
                            $args=’&suppress_filters=true&posts_per_page=’.$nummusic.’&post_type=oswc_music_reviews&order=DESC&orderby=’.$feedsort.$metakey;
                            $cust_loop = new WP_Query($args);
                            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                                // if we’re sorting by rating and this item does not have a rating, hide it
                                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                                    ?>
                                    <li>
                                         
                                        <?php oswc_show_rating($rating);
                                         
                                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                                         
                                    </li>
                                     
                                <?php } ?>
                                 
                            <?php endwhile;
                            endif;
                            wp_reset_query();
                             
                            <li class=»last gentesque tooltip» title=»View all music reviews»><a href=»music-reviews/»>More</a></li>
        
                        </ul>
                    </div>
                     
                <?php } ?>
                 
                <?php if($showgames) { ?>
                     
                    <div id=»tabs-games» class=»tabdiv»>
                        <ul>
                            <?php // setup the query
                            $args=’&suppress_filters=true&posts_per_page=’.$numgames.’&post_type=oswc_game_reviews&order=DESC&orderby=’.$feedsort.$metakey;
                            $cust_loop = new WP_Query($args);
                            if ($cust_loop->have_posts()) : while ($cust_loop->have_posts()) : $cust_loop->the_post();
                                // if we’re sorting by rating and this item does not have a rating, hide it
                                $rating = get_post_meta(get_the_ID(), «Rating», $single = true);
                                if(($rating && $feedsort==»meta_value») || ($feedsort!=»meta_value»)) {
                                    ?>
                                    <li>
                                         
                                        <?php oswc_show_rating($rating);
                                         
                                        <a class=»post-title» href=»<?php the_permalink(); ?>» title=»<?php the_title(); ?>»><?php the_title();
                                         
                                    </li>
                                     
                                <?php } ?>
                                 
                            <?php endwhile;
                            endif;
                            wp_reset_query();
                             
                            <li class=»last gentesque tooltip» title=»View all video game reviews»><a href=»game-reviews/»>More</a></li>
        
                        </ul>
                    </div>
                     
                <?php } ?>
             
            </div>
                                      
        </div>
         
    <?php
    }
    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
         
        $sort = $instance[‘sort’];
        $showmovies = $instance[‘showmovies’];
        $showmusic = $instance[‘showmusic’];
        $showgames = $instance[‘showgames’];
        $nummovies = $instance[‘nummovies’];
        $nummusic = $instance[‘nummusic’];
        $numgames = $instance[‘numgames’];
 
        /* Strip tags (if needed) and update the widget settings.
        $instance[‘sort’] = strip_tags( $new_instance[‘sort’] );
        $instance[‘showmovies’] = isset( $new_instance[‘showmovies’] );
        $instance[‘showmusic’] = isset( $new_instance[‘showmusic’] );
        $instance[‘showgames’] = isset( $new_instance[‘showgames’] );
        $instance[‘nummovies’] = strip_tags( $new_instance[‘nummovies’] );
        $instance[‘nummusic’] = strip_tags( $new_instance[‘nummusic’] );
        $instance[‘numgames’] = strip_tags( $new_instance[‘numgames’] );
 
        return $instance;
    }
    function form( $instance ) {
 
        /* Set up some default widget settings.
        $defaults = array( ‘sort’ => ‘latest’, ‘showmovies’ => true, ‘showmusic’ => true, ‘showgames’ => true, ‘nummovies’ => 10, ‘nummusic’ => 10, ‘numgames’ => 10 );
        $instance = wp_parse_args( (array) $instance, $defaults );
         
        <p>
            <input class=»radio» type=»radio» <?php if($instance[‘sort’]==’highest-rated’) { ?>checked <?php } ?>name=»<?php echo $this->get_field_name( ‘sort’ ); ?>» value=»highest-rated» />
            Order reviews by highest rated<br />
            <input class=»radio» type=»radio» <?php if($instance[‘sort’]!=’highest-rated’) { ?>checked <?php } ?>name=»<?php echo $this->get_field_name( ‘sort’ ); ?>» value=»latest» />
            Order reviews by latest
        </p>
     
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showmovies’]) ? $instance[‘showmovies’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘nummovies’ ); ?>» name=»<?php echo $this->get_field_name( ‘nummovies’ ); ?>» value=»<?php echo $instance[‘nummovies’]; ?>» style=»width:30px» />
            movie reviews
             
        </p>
 
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showmusic’]) ? $instance[‘showmusic’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘nummusic’ ); ?>» name=»<?php echo $this->get_field_name( ‘nummusic’ ); ?>» value=»<?php echo $instance[‘nummusic’]; ?>» style=»width:30px» />
            music reviews
             
        </p>
 
        <p>
            <input class=»checkbox» type=»checkbox» <?php checked(isset( $instance[‘showgames’]) ? $instance[‘showgames’] : 0 );
            Display
            <input id=»<?php echo $this->get_field_id( ‘numgames’ ); ?>» name=»<?php echo $this->get_field_name( ‘numgames’ ); ?>» value=»<?php echo $instance[‘numgames’]; ?>» style=»width:30px» />
            game reviews
             
        </p>
         
        <?php
    }
}
//LOAD THE WIDGET
add_action(«widgets_init», «oswc_load_widgets»);
function oswc_load_widgets()
{
    register_widget(‘oswc_tabbed_latest_reviews’);
}

Вот и все для нашего виджета. Последнее, что нужно сделать в нашем файле functions.php: создать функцию, которую мы вызвали выше, которая выводит HTML для рейтинга звезд. Вот функция, которую вы должны добавить ниже кода виджета, который вы добавили выше:

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
//html display of stars
function oswc_show_rating($rating) {
    $output = ‘<div class=»stars»>’;
    $output .= ‘<div class=»star’;
    if($rating>=1) {
        $output .= ‘ full’;
    } elseif($rating>0) {
        $output .= ‘ half’;
    }
    $output .= ‘»> </div>’;
    $output .= ‘<div class=»star’;
    if($rating>=2) {
        $output .= ‘ full’;
    } elseif($rating>1) {
        $output .= ‘ half’;
    }
    $output .= ‘»> </div>’;
    $output .= ‘<div class=»star’;
    if($rating>=3) {
        $output .= ‘ full’;
    } elseif($rating>2) {
        $output .= ‘ half’;
    }
    $output .= ‘»> </div>’;
    $output .= ‘<div class=»star’;
    if($rating>=4) {
        $output .= ‘ full’;
    } elseif($rating>3) {
        $output .= ‘ half’;
    }
    $output .= ‘»> </div>’;
    $output .= ‘<div class=»star’;
    if($rating>=5) {
        $output .= ‘ full’;
    } elseif($rating>4) {
        $output .= ‘ half’;
    }
    $output .= ‘»> </div>’;
    $output .= ‘</div>’;
    echo $output;
}

«Звездные изображения, которые использует этот виджет, содержатся в файле загрузки для этого урока».

Эта функция принимает значение рейтинга (число от 0 до 5, но включает в себя) и использует операторы if … else, чтобы проверить и посмотреть, сколько звезд желтеет, а сколько звезд серого. Он отображает div с классом «звезда» пять раз подряд и каждый раз проверяет рейтинг и сравнивает его с отображаемой звездой, а также добавляет класс «полный», если рейтинг больше или равен текущая звезда или класс «половина», если рейтинг выше, чем у предыдущей звезды.

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

Примечание: все звезды находятся внутри элемента div с классом «stars», и именно на это мы нацелимся, чтобы применить наши стили позже.


Теперь, когда мы выполнили всю работу по кодированию нашего виджета, WordPress распознает его на странице виджетов, и мы можем настроить его на нашей боковой панели. Перейдите в Внешний вид >> Виджеты и перетащите наш новый виджет, называемый вкладками «Последние отзывы» , на одну из боковых панелей. Мы будем использовать Первичную область виджетов в теме TwentyTen. Разверните настройки виджета, чтобы увидеть доступные опции, которые мы настроили на предыдущем шаге:

Выберите способ сортировки виджета (по наивысшему или последнему), выберите отображение каждого из трех типов обзора и укажите, сколько из каждого типа обзора вы хотите отобразить. Сохраните ваши настройки, и теперь у вас будет (несколько) работающий виджет на вашем сайте. Конечно, мы еще не применили ни один стиль, поэтому он не будет выглядеть слишком красиво, пока мы не выполним следующие два шага: применение jQuery и CSS.


Этот виджет использует пользовательский интерфейс jQuery для перехода по вкладкам. Итак, нам нужно сделать три простых вещи, чтобы подключить jQuery UI к нашему виджету: 1) загрузить библиотеку jQuery, 2) загрузить плагин jQuery UI и 3) вызвать функцию вкладок jQuery UI в нашем виджете.

WordPress поставляется с уже включенным jQuery. Некоторые люди предпочитают загружать его из CDN или даже загружать библиотеку и использовать ее в своей теме. Чтобы узнать о загрузке jQuery в WordPress, посетите Кодекс . Чтобы включить его в тему TwentyTen, все, что нам нужно сделать, — это всего одна строка кода в файле header.php. Откройте файл header.php и добавьте следующий вызов jQuery перед функцией wp_head () (так, чтобы это было где-то перед строкой 51 в теме TwentyTen):

1
<?php wp_enqueue_script(«jquery»);

Это та же техника, что и при загрузке библиотеки jQuery, за исключением того, что мы хотим вызвать ее после функции wp_head () (так что это будет где-то после строки 51 в теме TwentyTen):

1
<script type=»text/javascript» src=»http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.3/jquery-ui.min.js»></script>

Добавьте следующий код непосредственно после только что добавленного кода пользовательского интерфейса jQuery:

1
2
3
4
5
6
<script type=»text/javascript»>
    jQuery.noConflict();
    jQuery(document).ready(function() {
        jQuery(‘#tabbed-reviews > ul’).tabs({ fx: { opacity: ‘toggle’, duration: 200 } });
    });
</script>

Мы просто вызываем функцию tabs (которую предоставляет нам jQuery UI) в неупорядоченном списке внутри тега div # tabbed-reviews, и мы применяем переключатель непрозрачности для переходов между вкладками. Вы можете уменьшить продолжительность для более быстрого переключения или увеличить его для более медленного переключения (думайте об этом числе как о задержке вместо скорости).


Если вы просматриваете свой виджет прямо сейчас, вы, вероятно, не будете очень довольны, так как мы его вообще не стилизовали. Последний шаг — применить некоторые CSS-правила, которые сделают наш виджет действительно похожим на виджет и будут функционировать правильно. Откройте свой файл style.css и добавьте следующий стиль в конец файла:

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*************************************************
jquery tabs
*************************************************/
#tabbed-reviews a {
    font-family:Arial, Helvetica, sans-serif;
}
#tabbed-reviews a:hover {
    text-decoration:none;
}
ul.tabnav {
    margin:0px !important;
    padding:0px !important;
}
ul.tabnav li {
    display: inline;
    list-style: none;
}
ul.tabnav li a {
    text-decoration: none;
    text-transform: uppercase;
    color: #444;
    font-weight: bold;
    display:inline-block;
    padding: 5px 9px 6px 9px;
    outline: none;
    font-size:.8em;
}
ul.tabnav li a:hover, ul.tabnav li a:active, ul.tabnav li.ui-tabs-selected a {
    color:#FFF;
    background:url(images/sidebar-header-bg.png) repeat-x 0px 0px;
}
.tabdiv-wrapper {
    border:1px solid #CCC;
    margin-bottom:20px;
}
.tabdiv {
    background: #E8E8E8;
    border:1px solid #FFF;
    border-top:0px;
    font-size:1em;
}
.tabdiv ul {
    margin:0px !important;
}
.tabdiv li {
    list-style-type:none;
    list-style-image: none !important
}
.tabdiv li a {
    display:block;
    padding:10px 10px;
    border-bottom:1px solid #ccc;
    border-top:1px solid #fff;
    color:#444;
}
.tabdiv li a:hover {
    background:#F0F0F0;
    color:#222;
}
.tabdiv li.last a {
    text-align:center;
    font-weight:bold;
    text-transform:uppercase;
    color:#666;
    font-size:1em;
    padding:2px 0px 2px 0px;
    border-bottom:0px;
}
.ui-tabs-hide {
    display: none;
}
 
/*stars*/
.tabdiv .stars {
    float:right;
    margin-top:3px;
}
.tabdiv .stars {
    margin:10px 5px 0px 0px !important;
}
.tabdiv .star {
    width:14px;
    height:14px;
    float:left;
    margin-left:2px;
    background:url(images/star-empty-small.png) no-repeat 0px 0px;
}
.tabdiv .star.half {
    background:url(images/star-half-small.png) no-repeat 0px 0px;
}
.tabdiv .star.full {
    background:url(images/star-full-small.png) no-repeat 0px 0px;
}

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


Разработка в WordPress — это использование различных технологий, чтобы предоставить посетителям вашего сайта богатый пользовательский опыт. В этом уроке мы использовали стандартные основные функции WordPress, включая настраиваемые типы записей и API пользовательских виджетов, и мы расширили его, добавив полезную библиотеку jQuery, а затем плагин jQuery UI и, наконец, мы использовали мощь CSS для чтобы все выглядело гладко и профессионально.

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

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