Статьи

Как отображать метабоксы в соответствии с текущим форматом записи

Сегодня я хотел бы показать вам, как идти дальше с пользовательскими метабоксами и, в частности, как использовать их в соответствии с форматами записей.

Мы не будем рассказывать о том, как создавать повторно используемые пользовательские метабоксы, как это уже было рассмотрено в предыдущей теме, поэтому, если у вас возникнут какие-либо проблемы, обратитесь к этой статье


Перво-наперво, если вы никогда не слышали о них раньше, форматы постов позволяют отображать пост разными способами, в зависимости от того, какой «формат» поста вы установили (изображение, ссылка, галерея и т. Д.).

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

1
add_theme_support( ‘post-formats’, array( ‘link’, ‘quote’ ) );

Теперь с этим примером вы сможете использовать два формата постов: «ссылка» и «цитата».

Two metaboxes with a simple text input inside

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


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

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

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
$metaboxes = array(
    ‘link_url’ => array(
        ‘title’ => __(‘link information’, ‘twentyeleven’),
        ‘applicableto’ => ‘post’,
        ‘location’ => ‘normal’,
        ‘display_condition’ => ‘post-format-link’,
        ‘priority’ => ‘low’,
        ‘fields’ => array(
            ‘l_url’ => array(
                ‘title’ => __(‘link url:’, ‘twentyeleven’),
                ‘type’ => ‘text’,
                ‘description’ => »,
                ‘size’ => 60
            )
        )
    ),
    ‘quote_author’ => array(
        ‘title’ => __(‘quote author’, ‘twentyeleven’),
        ‘applicableto’ => ‘post’,
        ‘location’ => ‘normal’,
        ‘display_condition’ => ‘post-format-quote’,
        ‘priority’ => ‘low’,
        ‘fields’ => array(
            ‘q_author’ => array(
                ‘title’ => __(‘quote author:’, ‘twentyeleven’),
                ‘type’ => ‘text’,
                ‘description’ => »,
                ‘size’ => 20
            )
        )
    )
);

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

Теперь мы создадим три функции для добавления, обновления / сохранения и отображения метабоксов.

01
02
03
04
05
06
07
08
09
10
11
add_action( ‘admin_init’, ‘add_post_format_metabox’ );
 
function add_post_format_metabox() {
    global $metaboxes;
 
    if ( ! empty( $metaboxes ) ) {
        foreach ( $metaboxes as $id => $metabox ) {
            add_meta_box( $id, $metabox[‘title’], ‘show_metaboxes’, $metabox[‘applicableto’], $metabox[‘location’], $metabox[‘priority’], $id );
        }
    }
}

По сути, мы просто используем наши ранее определенные опции для добавления этих метабоксов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function show_metaboxes( $post, $args ) {
    global $metaboxes;
 
    $custom = get_post_custom( $post->ID );
    $fields = $tabs = $metaboxes[$args[‘id’]][‘fields’];
 
    /** Nonce **/
    $output = ‘<input type=»hidden» name=»post_format_meta_box_nonce» value=»‘ . wp_create_nonce( basename( __FILE__ ) ) . ‘» />’;
 
    if ( sizeof( $fields ) ) {
        foreach ( $fields as $id => $field ) {
            switch ( $field[‘type’] ) {
                default:
                case «text»:
 
                    $output .= ‘<label for=»‘ . $id . ‘»>’ .
 
                    break;
            }
        }
    }
 
    echo $output;
}

Пока что это то, что мы должны иметь на новом экране администратора:

Two metaboxes with a simple text input inside
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
add_action( ‘save_post’, ‘save_metaboxes’ );
 
function save_metaboxes( $post_id ) {
    global $metaboxes;
 
    // verify nonce
    if ( ! wp_verify_nonce( $_POST[‘post_format_meta_box_nonce’], basename( __FILE__ ) ) )
        return $post_id;
 
    // check autosave
    if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE )
        return $post_id;
 
    // check permissions
    if ( ‘page’ == $_POST[‘post_type’] ) {
        if ( ! current_user_can( ‘edit_page’, $post_id ) )
            return $post_id;
    } elseif ( ! current_user_can( ‘edit_post’, $post_id ) ) {
        return $post_id;
    }
 
    $post_type = get_post_type();
 
    // loop through fields and save the data
    foreach ( $metaboxes as $id => $metabox ) {
        // check if metabox is applicable for current post type
        if ( $metabox[‘applicableto’] == $post_type ) {
            $fields = $metaboxes[$id][‘fields’];
 
            foreach ( $fields as $id => $field ) {
                $old = get_post_meta( $post_id, $id, true );
                $new = $_POST[$id];
 
                if ( $new && $new != $old ) {
                    update_post_meta( $post_id, $id, $new );
                }
                elseif ( » == $new && $old || ! isset( $_POST[$id] ) ) {
                    delete_post_meta( $post_id, $id, $old );
                }
            }
        }
    }
}

Хорошо, теперь у нас все готово, и мы можем добавлять и обновлять мета-записи для каждой статьи и отображать их внутри метабоксов. Теперь мы можем разобраться в нашей проблеме: отобразить правильный метабокс, соответствующий текущему формату записи.


Для этого мы будем использовать jQuery для обработки событий show, hide и radio change.

Чтобы добавить встроенный JavaScript только в разделе администратора, мы можем использовать этот хук действия:

1
add_action( ‘admin_print_scripts’, ‘display_metaboxes’, 1000 );

Приоритет установлен на 1000, чтобы гарантировать, что jQuery был загружен первым.

Мы могли бы установить более точный хук, такой как admin_print_scripts-post или admin_print_scripts-post-new , но по какой-то причине, если это так, jQuery вызывается после того, как наш скрипт напечатан.

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

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

Мы также собираемся создать (все еще через PHP) объект JavaScript, который мы будем использовать для привязки идентификатора переключателя формата записи к идентификатору метабокса.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
function display_metaboxes() {
    global $metaboxes;
    if ( get_post_type() == «post» ) :
        ?>
        <script type=»text/javascript»>// <![CDATA[
            $ = jQuery;
 
            <?php
            $formats = $ids = array();
            foreach ( $metaboxes as $id => $metabox ) {
                array_push( $formats, «‘» . $metabox[‘display_condition’] . «‘: ‘» . $id . «‘» );
                array_push( $ids, «#» . $id );
            }
            ?>
 
            var formats = { <?php echo implode( ‘,’, $formats );?> };
            var ids = «<?php echo implode( ‘,’, $ids ); ?>»;

Затем мы отобразим правильный метабокс после загрузки страницы, выбрав текущий формат поста (установленный переключатель) и исчезнув в соответствующем метабоксе (используя объект formats ).

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

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
            function displayMetaboxes() {
                // Hide all post format metaboxes
                $(ids).hide();
                // Get current post format
                var selectedElt = $(«input[name=’post_format’]:checked»).attr(«id»);
 
                // If exists, fade in current post format metabox
                if ( formats[selectedElt] )
                    $(«#» + formats[selectedElt]).fadeIn();
            }
 
            $(function() {
                // Show/hide metaboxes on page load
                displayMetaboxes();
 
                // Show/hide metaboxes on change event
                $(«input[name=’post_format’]»).change(function() {
                    displayMetaboxes();
                });
            });
 
        // ]]></script>
        <?php
    endif;
}

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


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

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