Статьи

Лучший виджет списка форумов для bbPress

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

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

Виджет Список форумов на форуме поддержки bbPress
Виджет Список форумов на форуме поддержки bbPress

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


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

1
2
3
4
5
6
7
8
9
<?php
/*
Plugin Name: Better Forum List Widget for bbPress
Description: The default bbPress Forum List widget is pretty bare bones.
Author: c.bavota
Version: 1.0.0
Author URI: http://www.bavotasan.com/
*/
// TODO ?>

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


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

Вот как выглядит базовый код Widget API:

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

Этот учебник на самом деле не о тонкостях API Widget, поэтому я предлагаю взглянуть на API Widgets в Кодексе WordPress .


Давайте пройдемся по коду API по одному блоку за раз. Во-первых, вам нужно добавить некоторую основную информацию о виджете:

1
2
3
4
public function __construct() {
    $widget_ops = array( ‘classname’ => ‘bbp_forums_topic_count_widget_options’, ‘description’ => __( ‘A list of categorized forums with their topic count’ ) );
    parent::__construct( false, __( ‘(bbPress) Forums List with Topic Count’ ), $widget_ops );
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function widget( $args, $instance ) {
    extract( $args );
    $title = apply_filters( ‘bbp_forum_widget_title’, $instance[‘title’] );
 
    echo $before_widget;
 
    if ( ! empty( $title ) )
        echo $before_title .
    ?>
    <ul>
        <?php
        wp_list_pages( array(
            ‘title_li’ => »,
            ‘post_type’ => bbp_get_forum_post_type(),
            ‘sort_column’ => ‘menu_order’,
            ‘walker’ => new Forum_List_Walker,
            ‘no_found_rows’ => true,
        ) );
        ?>
    </ul>
    <?php
    echo $after_widget;
}
// TODO ?>

В виджете есть только одна опция, поэтому для формы администратора просто необходимо следующее:

01
02
03
04
05
06
07
08
09
10
11
public function form( $instance ) {
    $title = empty( $instance[‘title’] ) ?
    ?>
    <p>
        <label for=»<?php echo $this->get_field_id( ‘title’ ); ?>»><?php _e( ‘Title:’ );
            <input class=»widefat» id=»<?php echo $this->get_field_id( ‘title’ ); ?>» name=»<?php echo $this->get_field_name( ‘title’ ); ?>» type=»text» value=»<?php echo $title; ?>» />
        </label>
    </p>
    <?php
}
// TODO ?>

При наличии только одной опции ввода блок обновления требует простой проверки:

1
2
3
4
5
6
public function update( $new_instance, $old_instance ) {
    $instance = $old_instance;
    $instance[‘title’] = strip_tags( $new_instance[‘title’] );
 
    return $instance;
}

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

1
2
3
add_action( ‘widgets_init’, function() {
    register_widget( ‘BBP_Forums_Topic_Count_Widget’ );
} );

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

Я предлагаю почитать на уроке, потому что это немного сложно. К счастью, мне удалось взломать его, чтобы получить то, что мне нужно для плагина.

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
class Forum_List_Walker extends Walker {
    var $tree_type = ‘page’;
    var $db_fields = array (
        ‘parent’ => ‘post_parent’,
        ‘id’ => ‘ID’
    );
 
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( «\t», $depth );
        $output .= «\n$indent<ul class=’children’>\n»;
    }
 
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat( «\t», $depth );
        $output .= «$indent</ul>\n»;
    }
 
    function start_el( &$output, $page, $depth, $args ) {
        $indent = ( $depth ) ?
 
        extract( $args, EXTR_SKIP );
        $css_class = array();
        $has_children = forum_list_widget_has_children( $page->ID );
        if ( ! bbp_is_single_user() && $current_page = get_the_ID() ) {
            $_current_page = get_post( $current_page );
            if ( in_array( $page->ID, $_current_page->ancestors ) )
                $css_class[] = ‘current_forum_ancestor’;
            if ( $has_children )
                $css_class[] = ‘forum_category’;
            if ( $page->ID == $current_page )
                $css_class[] = ‘current_forum_item’;
            elseif ( $_current_page && $page->ID == $_current_page->post_parent )
                $css_class[] = ‘current_forum_parent’;
        } elseif ( $page->ID == get_option( ‘page_for_posts’ ) ) {
            $css_class[] = ‘current_forum_parent’;
        }
 
        $css_class = implode( ‘ ‘, $css_class );
        $topic_count = ( $has_children ) ?
        $forum_item = ( $has_children ) ?
 
        $output .= $indent .
    }
 
    function end_el( &$output, $page, $depth = 0, $args = array() ) {
        $output .= «</li>\n»;
    }
 
}

Обходчик также использует небольшое условное имя forum_list_widget_has_children() которое проверяет, есть ли на странице подстраницы.

01
02
03
04
05
06
07
08
09
10
function forum_list_widget_has_children( $page_id ) {
    $children = get_pages( array(
        ‘child_of’ => $page_id,
        ‘post_type’ => bbp_get_forum_post_type(),
    ) );
    if ( $children )
        return true;
    else
        return false;
}

Требуется лишь немного CSS, чтобы все выглядело хорошо.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
.forum_category_title {
    font-size: 1.2em;
    padding: 5px 0 0;
    display: block;
    font-weight: bold;
    }
 
.topic-count {
    float: right;
    }
 
.bbp_forums_topic_count_widget_options a {
    text-decoration: none;
    }
 
    .bbp_forums_topic_count_widget_options ul.children {
        padding: 0 0 0 5px;
        margin: 0;
        }

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

1
2
3
4
add_action( ‘wp_enqueue_scripts’, ‘forum_list_widget_styles’ );
function forum_list_widget_styles() {
    wp_enqueue_style( ‘forum_list_widget_styles’, plugins_url( ‘/css/style.css’, __FILE__ ) );
}

Если вы хотите увидеть все вместе в плагине, вы можете скачать его выше. Установите его и добавьте новый виджет Список форумов на свою боковую панель, и вы увидите что-то вроде этого:

Конечный результат
Конечный результат

Теперь ваш список будет лучше организован и отображает общее количество тем для каждого форума.

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