WordPress Meta Boxes: полное руководство разработчика

WordPress Meta Boxes: полное руководство разработчика

CMS 15.09.2017

В этом уроке я буду пытаться охватить все, что вы, возможно, хотите знать об использовании Meta Boxes в WordPress. Несмотря на то, что можно добавить Meta Boxes непосредственно к теме, лучшая практика добавить Meta Boxes через плагин. В этом уроке, мы создадим плагин, чтобы добавить Meta Boxes к редактору WordPress.

Полный плагин доступен на GitHub .

Функция add_meta_box () была добавлена в WordPress в версии 2.5, так что она уже была описана ранее. Если вы читали о ней, то будете вкурсе как она работает. Так что поехали…

1. Создайте новый плагин

Я не буду вдаваться в подробности создания нашего плагина здесь. Лучшие практики уже обсудили это в других местах. Для целей этого урока мы создадим папку под названием «custom-meta-box-template». Внутри этой папки, мы создадим файл с именем «custom-meta-box-template.php» и поместите следующий текст в начало файла:

<?php /* Plugin Name: Custom Meta Box Template Plugin URI: http://themefoundation.com/ Description: Provides a starting point for creating custom meta boxes. Author: Theme Foundation Version: 1.0 Author URI: http://themefoundation.com/ */ 

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

2. Добавьте новый meta box

Добавить новый meta box довольно просто. Мы начнем, разместив следующий код в файле custom-meta-box-template.php, который мы только что создали.

/**
  * Adds a meta box to the post editing screen
*/
function prfx_custom_meta() {
    add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'post' );
}
add_action( 'add_meta_boxes', 'prfx_custom_meta' );

Здесь мы создаем функцию под названием «prfx_custom_meta» и присоединияем его к хуку действия «add_meta_boxes» (Если вы не понимаете как работают хуки действий WordPress — почитайте Introduction to WordPress Action Hooks). Эта функция имеет только одну строку, и она вызывается add_meta_box () function. В приведенном выше коде, мы использовали только четыре требуемых параметров из семи, принятых с помощью функции «add_meta_box». Вот все семь.

Function: add_meta_box()
$id string Уникальный ID для этого meta box.
$title string Строка для названия meta box. Обратите внимание: Если meta box который вы создаете будет добавлен в публичный релиз (в тему, плагин или т.д), эта строка должна быть интернационализирована
$callback string Имя функции, которая будет выводить содержимое meta box.
$post_type string Тип поста, где должен отображаться этот meta box.
$context string Необязательный. Определяет раздел страницы, где meta box должн быть размещен (normal, advanced, or side). По умолчанию: normal.
$priority string Необязательный. Определяет порядок внутри секции, где meta box будет размещен (high, core, default, or low). По умолчанию: default.
$callback_args array Необязательный. Массив аргументов, которые могут быть переданы в функцию обратного вызова.

Перед тем, как идти редактировать пост, чтобы проверить наш новый meta box, нам нужно создать функцию обратного вызова, которая будет выводить содержимое meta поле. Помните, что название этой функции должно соответствовать строке, которую мы использовали в качестве параметра $callback выше.

/**
 * Outputs the content of the meta box
*/
function prfx_meta_callback( $post ) {
	echo 'This is a meta box';  
}

Теперь, если мы идем создать новый или изменить существующий пост, мы должны увидеть наш новый meta box, что-то вроде этого.

wordpress

3. Добавьте поле ввода в meta box

Теперь, когда наш новый meta box работает, давайте добавим поле формы вместо строки «This is a meta box». Мы можем сделать это полностью заменив старую функцию обратного вызова callback с этим обновлением:

/**
 * Outputs the content of the meta box
*/
function prfx_meta_callback( $post ) {
	wp_nonce_field( basename( __FILE__ ), 'prfx_nonce' );
	$prfx_stored_meta = get_post_meta( $post->ID );
	?>

	<p>
		<label for="meta-text" class="prfx-row-title"><?php _e( 'Example Text Input', 'prfx-textdomain' )?></label>
		<input type="text" name="meta-text" id="meta-text" value="<?php if ( isset ( $prfx_stored_meta['meta-text'] ) ) echo $prfx_stored_meta['meta-text'][0]; ?>" />
	</p>

	<?php
}

Сначала мы создаем имя для одноразового использования в целях безопасности (prfx_nonce). Далее, мы получаем всю meta-информацию сохраненную с помощью этой записи, используя функцию get_post_meta (). Эта функция будет объяснена чуть позже, когда мы используем наш сохраненный meta input в теме.

Наконец, у нас есть label и input. Довольно стандартный для формы. Не обращайте внимание на класс «prfx-row-titl». Он придет в игру позже, когда мы начнем стилизации форму с помощью CSS. Обратите внимание, что значение input отображается с помощью переменной $prfx_stored_meta, которое мы установили с помощью функции get_post_meta (). Он ничего не отображается еще, так как мы не добавили код, чтобы сохранить ввод, но в конце концов input заполнится ранее сохраненным текстом. Это приводит нас к следующему шагу в этой статье.

4. Сохраните meta box input

Давайте начнем с кода, а затем посмотрим, что он делает.

/**
 * Saves the custom meta input
 */
function prfx_meta_save( $post_id ) {
 
    // Checks save status
    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ 'prfx_nonce' ] ) && wp_verify_nonce( $_POST[ 'prfx_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
 
    // Exits script depending on save status
    if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
        return;
    }
 
    // Checks for input and sanitizes/saves if needed
    if( isset( $_POST[ 'meta-text' ] ) ) {
        update_post_meta( $post_id, 'meta-text', sanitize_text_field( $_POST[ 'meta-text' ] ) );
    }
 
}
add_action( 'save_post', 'prfx_meta_save' );

Первая часть функции проверяет, чтобы убедиться, что мы действительно хотим сохранить meta-input и это не автосохранение.

Вторая часть функции проверяет введены ли данные в input, который мы создали. Если есть текст, чтобы сохранить, он использует функцию update_post_meta (), чтобы сохранить текст в базу данных. Эта функция имеет 4 параметра:

Function: update_post_meta()
$post_id integer Задает ID поста у которого вы будете изменять значение произвольного поля. Обязательный парамет
$meta_key string Задает ключ поля, которое будет отредактировано.
$meta_value string Новое значение для произвольного поля. Переданный массив будет сериализован в строку. Обязательный параметр.
$prev_value string Необязательный параметр. Представляет собой старое значение произвольного поля, которое вы хотите изменить. Различает несколько полей с одинаковым ключом. Если он опущен, и есть несколько строк на 1 запись и мета (произвольное) поле, то тогда будут обновлены все мета значения. По умолчанию равен пустой строке.

Таким образом, в приведенном выше коде мы использовали параметры post-ID, идентификатор нашего input и значение input. Тем не менее, обратите внимание, что мы не дали ей значение input непосредственно. Вместо этого мы использовали функцию sanitize с целью подготовки значения перед помещением его в базу данных. Это не статья о проверке и валидации, но если вы работаете со значениями введенными пользователем, вы никогда не должны пропускать значения введенные пользователем без проверки в базу данных.

5. Использование сохраненных meta данных

Теперь, когда мы успешно сохранили наши meta данные, пришло время, чтобы использовать их в теме. Я не дам вам точное место куда поместить этот код, потому что оно будет варьироваться в зависимости от того, что вы пытаетесь сделать. Во всяком случае, вот код, который мы хотим использовать в нашем файле шаблона:

<?php
 
    // Retrieves the stored value from the database
    $meta_value = get_post_meta( get_the_ID(), 'meta-text', true );
 
    // Checks and displays the retrieved value
    if( !empty( $meta_value ) ) {
        echo $meta_value;
    }
 
?>

Есть несколько вещей, на которые следует обратить внимание в этом коде. Во-первых это функция get_post_meta (). Эта функция может иметь несколько параметров, поэтому убедитесь, что прочитать таблицу ниже тщательно.

Function: get_post_meta()
$post_id integer ID поста, произвольные поля которого нужно получить. Мы можем получить ID редактируемого поста используя get_the_ID().
$key string Название произвольного поля, значение которого нужно получить. Если оставить поле пустым, будут получены все произвольные поля поста.
$single boolean Если выставить параметр в true, то функция вернет единственное значение в видестроки. Если параметр будет равен false или не будет установлен, то функция вернетмассив значений произвольных полей.
Однако, если в значении произвольного поля находится сериализованный массив, то значение true вернет, нормальный массив, а если указать false, то вернется массив в элементе «[0]» которого будет все тот же сериализованный массив. Т.е. в этом случае параметр работает «наоборот».

И, наконец, мы хотим убедиться, что значение было возвращено перед выводом его на страницу. Теперь вы можете думать, «мы не могли просто вывести его на страницу без проверки, чтобы убедиться, что значение было возвращено?» … И это действительно вопрос. На самом деле, ответ да! Вы можете определенно сделать это. Однако, имейте в виду, что в большинстве случаев вы будете использовать это значение в каком-то HTML-элементе, если использовать это в реальной жизненной ситуации, а не в статье. Как правило, если значение не возвращается, вы не хотите выводить пустой HTML-элемент. Вот почему здесь включено if( !emtpy ), даже если оно не является необходимым.

6. Дополнительные положения meta box

До сих пор мы работали над meta box, которое отображается в нижней части экрана страницы редактирования поста. Теперь давайте переместим его. Помните, в начале этого урока, когда мы впервые добавили meta box к экрану редактирования поста с помощью функции add_meta_box ()? Были еще несколько параметров, которые мы не использовали в то время: $context и $priority. Давайте использовать их сейчас, а также в качестве параметра $post_type , с которым мы уже знакомы. Если вы нашли время, чтобы построить пользовательский meta box, вы, вероятно, не хотите, чтобы он был помещен ниже всех meta box по умолчанию на экране редактирования (Excerpt, Discussion, Comments, Revisions, и т.д.). Если вы хотите поместить наш meta box выше meta box по умолчанию, вы можете заменить наш первоначальный вызов функции add_meta_box() с этим:

add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'post', 'normal', 'high' );

Обратите внимание на приоритет, установленный на «высокий» в последнем параметре.

Если вы хотите поместить его в боковой панели редактора страницы вместо главной строки редактора поста, вы можете использовать это:

add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'page', 'side' );

Или же вы можете добавить наш meta box во вложения средств массовой информации (attachment) воспользуйтесь этой строкой:

add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'attachment' );

Meta box так же могут быть добавлены к пользовательским типам данных. Нам просто нужно будет заменить параметр #4 в функции на тот тип данных который нам нужен. Для остальной части статьи, я собираюсь установить его обратно в исходные значение:

add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'post' );

7. Добавление стилей CSS к содержанию meta box

Когда мы начнем добавлять больше элементов для формы к нашему meta box, его вид становится не очень привлекательным. Для того, чтобы держать все в порядке, мы создадим файл с именем metabox.css и добавим в плагин базового каталога. Вставьте в него следующие стили:

#prfx_meta{
    overflow: hidden;
    padding-bottom: 1em;
}
 
#prfx_meta p{
    clear: both;
}
 
.prfx-row-title{
    display: block;
    float: left;
    width: 200px;
}
 
.prfx-row-content{
    float: left;
    padding-bottom: 1em;
}
 
.prfx-row-content label{
    display: block;
    line-height: 1.75em;
}

Здесь мы не пытаемся создать новый пользовательский интерфейс, а просто приводим форму в порядок. Мы используем класс «prfx-form-title», который мы уже упоминали ранее, чтобы элементы формы обтекали слева и мы могли дать им последовательную ширину. Это не учебник по CSS, так что я не буду объяснять каждый стиль в деталях. Это просто очень минимальный набор правил, чтобы дать форме вид согласованно макету.

Чтобы загрузить эту таблицу стилей на нужных админ-страницах WordPress, мы вернемся в файл custom-meta-box-template.php, добавим следующую функцию и присоединим её к хуку действия «admin_print_styles»:

/**
 * Adds the meta box stylesheet when appropriate
 */
function prfx_admin_styles(){
    global $typenow;
    if( $typenow == 'post' ) {
        wp_enqueue_style( 'prfx_meta_box_styles', plugin_dir_url( __FILE__ ) . 'meta-box-styles.css' );
    }
}
add_action( 'admin_print_styles', 'prfx_admin_styles' );

Это довольно простая функция, но мы хотим заметить пару вещей, прежде чем двигаться дальше. Во-первых, мы проверим, чтобы убедиться, что глобальная переменная $typenow соответствует параметру $post_type, который мы использовали, когда впервые вызывали add_meta_box (в данном случае, «post»).

Обратите внимание: этот метод не является совершенным. Например, этот метод будет загружать файл metabox.css на страницу админ-панели Posts > Categories, даже если он там не нужен. Тем не менее, он не будет загружен на других страницах меню админ-панели вне «Posts».

Во-вторых, есть функция wp_enqueue_style(), которая вызывается, если мы загружаем страницу записи post. Для наших целей здесь нам нужно только использовать первые два параметра этой функции. Первое — уникальное имя, которое мы даем нашей таблице стилей, а второе — это URL доступа к таблице стилей, чтобы она могла быть загружена.

8. Стандартные поля ввода meta box

Мы создали стандартное текстовое поле уже, так что давайте прыгнем в остальную часть стандартных типов форм ввода.

8.1 Checkboxes

Checkbox является немного более сложным, чем input, но не намного. Есть моменты, когда мы может захотеться использовать несколько checkbox в группе — это мы должны учитывать в способе, которым мы формируем наш HTML. Этот код будет идти чуть ниже текстового input, который мы создали в функции обратного вызова prfx_meta () ранее.

<p>
    <span class="prfx-row-title"><?php _e( 'Example Checkbox Input', 'prfx-textdomain' )?></span>
    <div class="prfx-row-content">
        <label for="meta-checkbox">
            <input type="checkbox" name="meta-checkbox" id="meta-checkbox" value="yes" <?php if ( isset ( $prfx_stored_meta['meta-checkbox'] ) ) checked( $prfx_stored_meta['meta-checkbox'][0], 'yes' ); ?> />
            <?php _e( 'Checkbox label', 'prfx-textdomain' )?>
        </label>
        <label for="meta-checkbox-two">
            <input type="checkbox" name="meta-checkbox-two" id="meta-checkbox-two" value="yes" <?php if ( isset ( $prfx_stored_meta['meta-checkbox-two'] ) ) checked( $prfx_stored_meta['meta-checkbox-two'][0], 'yes' ); ?> />
            <?php _e( 'Another checkbox', 'prfx-textdomain' )?>
        </label>
    </div>
</p>

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

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

// Checks for input and saves
if( isset( $_POST[ 'meta-checkbox' ] ) ) {
    update_post_meta( $post_id, 'meta-checkbox', 'yes' );
} else {
    update_post_meta( $post_id, 'meta-checkbox', '' );
}
 
// Checks for input and saves
if( isset( $_POST[ 'meta-checkbox-two' ] ) ) {
    update_post_meta( $post_id, 'meta-checkbox-two', 'yes' );
} else {
    update_post_meta( $post_id, 'meta-checkbox-two', '' );
}

Обратите внимание на то, что значение, которое мы сохранить в базу данных («yes») имеет то же значение, что и value в checkbox в предыдущем блоке кода. Я знаю, что я сказал, что не буду покрывать проверку данных, но при построении галочки с нуля, путем жесткого кодирования входного значения вроде этого (а не с помощью значения input, в который вводит пользователь), можно легко убедиться, что соответствующее значение будет записано в базу данных.

8.2 Radio Buttons

Так же, как с checkbox, каждая опция radio button имеет свой собственный label. Кроме того, как checkbox, мы используем функцию checked(), чтобы определить состояние каждой кнопки. Так же, как и раньше, мы добавим этот код в нижней части функции prfx_meta_callback() ниже нашего checkbox кода.

<p>
    <span class="prfx-row-title"><?php _e( 'Example Radio Buttons', 'prfx-textdomain' )?></span>
    <div class="prfx-row-content">
        <label for="meta-radio-one">
            <input type="radio" name="meta-radio" id="meta-radio-one" value="radio-one" <?php if ( isset ( $prfx_stored_meta['meta-radio'] ) ) checked( $prfx_stored_meta['meta-radio'][0], 'radio-one' ); ?>>
            <?php _e( 'Radio Option #1', 'prfx-textdomain' )?>
        </label>
        <label for="meta-radio-two">
            <input type="radio" name="meta-radio" id="meta-radio-two" value="radio-two" <?php if ( isset ( $prfx_stored_meta['meta-radio'] ) ) checked( $prfx_stored_meta['meta-radio'][0], 'radio-two' ); ?>>
            <?php _e( 'Radio Option #2', 'prfx-textdomain' )?>
        </label>
    </div>
</p>

В отличие от сохранения checkbox, когда мы сохраняем данные radio button, нам нужно сохранить только выбранные значения. Нам не нужно проверять каждое из них по отдельности, как мы это делали для checkbox. Следующий фрагмент кода должен быть размещен в нижней части функции prfx_meta_save() чуть ниже кода, который сохраняет значение checkbox.

// Checks for input and saves if needed
if( isset( $_POST[ 'meta-radio' ] ) ) {
    update_post_meta( $post_id, 'meta-radio', $_POST[ 'meta-radio' ] );
}

Теперь, когда мы сделали несколько различных элементов, я собираюсь начать двигаться немного быстрее. Просто помните, что код для отображения элементов формы идет в функции prfx_meta_callback(), а код для сохранения введенных данных в meta box в функции prfx_meta_save().

8.3 Список select

Select представляет собой отдельный элемент, так что мы можем начать с тега label, а не со span, который использовали в нескольких последних элементах. Тем не менее, при выборе select, существует целый ряд различных вариантов, поэтому нам по-прежнему необходимо определять состояние каждого варианта, когда мы отображаем его. Мы делаем это с помощью функции selected(), которая работает точно так же, как и функция checked(), которую мы используем с checkbox и radio button, за исключением того, что ее вывод является специфическим для выбора списков select.

<p>
    <label for="meta-select" class="prfx-row-title"><?php _e( 'Example Select Input', 'prfx-textdomain' )?></label>
    <select name="meta-select" id="meta-select">
        <option value="select-one" <?php if ( isset ( $prfx_stored_meta['meta-select'] ) ) selected( $prfx_stored_meta['meta-select'][0], 'select-one' ); ?>><?php _e( 'One', 'prfx-textdomain' )?></option>';
        <option value="select-two" <?php if ( isset ( $prfx_stored_meta['meta-select'] ) ) selected( $prfx_stored_meta['meta-select'][0], 'select-two' ); ?>><?php _e( 'Two', 'prfx-textdomain' )?></option>';
    </select>
</p>

Код, который мы используем для сохранения выбранного значения select выглядит так же, как код, используемый для сохранения выбранного значения radio button. Мы просто должны изменить «meta-radio» на «meta-select» и готово.

// Checks for input and saves if needed
if( isset( $_POST[ 'meta-select' ] ) ) {
    update_post_meta( $post_id, 'meta-select', $_POST[ 'meta-select' ] );
}

8.4 Textarea

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

<p>
    <label for="meta-textarea" class="prfx-row-title"><?php _e( 'Example Textarea Input', 'prfx-textdomain' )?></label>
    <textarea name="meta-textarea" id="meta-textarea"><?php if ( isset ( $prfx_stored_meta['meta-textarea'] ) ) echo $prfx_stored_meta['meta-textarea'][0]; ?></textarea>
</p>

Код для сохранения ввода textarea выглядит почти так же, как и последние несколько.

// Checks for input and saves if needed
if( isset( $_POST[ 'meta-textarea' ] ) ) {
    update_post_meta( $post_id, 'meta-textarea', $_POST[ 'meta-textarea' ] );
}

9. Дополнительные поля ввода meta box

Теперь, когда мы рассмотрели стандартные типы входа данных, давайте добавим некоторые специализированные полей вводов. Большинство из них будет требовать использования JavaScript. Для простоты (и для тех, кому нужно использовать только один из этих типов пользовательских полей вводов), я добавлю JavaScript, связанный с каждым типом поля ввода отдельно. Если вы используете несколько таких типов ввода, не стесняйтесь объединить JavaScript в один файл.

9.1 Color Picker (Выбор цвета)

Сначала мы создадим стандартный текстовый input, так же, как мы это делали в самом начале этого урока. Позже мы добавим некоторые JavaScript, чтобы преобразовать его с помощью палитры цветов, встроенной в сам WordPress.

<p>
    <label for="meta-color" class="prfx-row-title"><?php _e( 'Color Picker', 'prfx-textdomain' )?></label>
    <input name="meta-color" type="text" value="<?php if ( isset ( $prfx_stored_meta['meta-color'] ) ) echo $prfx_stored_meta['meta-color'][0]; ?>" class="meta-color" />
</p>

Далее, мы создадим файл и добавим в базовый каталог плагина с именем «meta-box-color.js» и добавим в него этот код:

jQuery(document).ready(function($){
    $('.meta-color').wpColorPicker();
});

Этим самым мы определим какой элемент превратить в реальную цветовую палитру. Обратите внимание на то, что «meta-color» соответствует класс, который мы дали нашему input в предыдущем шаге.

Теперь, когда наш Javascript файл был создан, нам нужно загружать его каждый раз, когда наш metabox загружен. Мы можем сделать это, перейдя обратно в custom-meta-box-template.php и добавив следующий блок кода:

/**
 * Loads the color picker javascript
 */
function prfx_color_enqueue() {
    global $typenow;
    if( $typenow == 'post' ) {
        wp_enqueue_style( 'wp-color-picker' );
        wp_enqueue_script( 'meta-box-color-js', plugin_dir_url( __FILE__ ) . 'meta-box-color.js', array( 'wp-color-picker' ) );
    }
}
add_action( 'admin_enqueue_scripts', 'prfx_color_enqueue' );

Эта функция начинается с проверки отображается ли этот пост на экран, так как наш meta box загружается только для постов. Если ваш meta box находится в другом месте, измените «post» в операторе if() на нужное вам значение. Другие места для meta box обсуждаются в разделе 6, «Дополнительные положения meta box». Ограничение использования переменной $typenow обсуждаются в разделе 7 «Добавление стилей CSS к содержанию meta box».

Если $typenow равно «post», то мы начинаем загрузку файлов. Во-первых, мы добавляем таблицы стилей «wp-color-picker», встроенные в WordPress. Она будет обрабатывать все CSS стили в палитре цветов. Далее, мы используем функцию wp_enqueue_script(), чтобы загрузить пользовательские файлы JavaScript, которые мы только что создали. В последней строке, мы подключаем хук функции «admin_enqueue_scripts», так что это загружается в нужное время.

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

// Checks for input and saves if needed
if( isset( $_POST[ 'meta-color' ] ) ) {
    update_post_meta( $post_id, 'meta-color', $_POST[ 'meta-color' ] );
}

… и это должно превратить непритязательное поле ввода input в рабочий color picker.

9.2 Загрузка изображений

Вот где вещи начинают становиться сложнее. Во-первых, давайте добавим еще один input в наш metabox. Input будет содержать URL нашего файла изображения. Мы будем также добавлять кнопку для открытия менеджера загрузки медафайлов WordPress, чтобы позволить WordPress самостоятельно загружать и размещать файлы при выборе и загрузке изображений через наш metabox.

<p>
    <label for="meta-image" class="prfx-row-title"><?php _e( 'Example File Upload', 'prfx-textdomain' )?></label>
    <input type="text" name="meta-image" id="meta-image" value="<?php if ( isset ( $prfx_stored_meta['meta-image'] ) ) echo $prfx_stored_meta['meta-image'][0]; ?>" />
    <input type="button" id="meta-image-button" class="button" value="<?php _e( 'Choose or Upload an Image', 'prfx-textdomain' )?>" />
</p>

Затем мы создадим файл meta-box-image.js в каталоге нашего плагина и добавим секцию JavaScript в него:

<p>
/*
 * Attaches the image uploader to the input field
 */
jQuery(document).ready(function($){
 
    // Instantiates the variable that holds the media library frame.
    var meta_image_frame;
 
    // Runs when the image button is clicked.
    $('#meta-image-button').click(function(e){
 
        // Prevents the default action from occuring.
        e.preventDefault();
 
        // If the frame already exists, re-open it.
        if ( meta_image_frame ) {
            meta_image_frame.open();
            return;
        }
 
        // Sets up the media library frame
        meta_image_frame = wp.media.frames.meta_image_frame = wp.media({
            title: meta_image.title,
            button: { text:  meta_image.button },
            library: { type: 'image' }
        });
 
        // Runs when an image is selected.
        meta_image_frame.on('select', function(){
 
            // Grabs the attachment selection and creates a JSON representation of the model.
            var media_attachment = meta_image_frame.state().get('selection').first().toJSON();
 
            // Sends the attachment URL to our custom image input field.
            $('#meta-image').val(media_attachment.url);
        });
 
        // Opens the media library frame.
        meta_image_frame.open();
    });
});

Есть несколько вещей, которые следует отметить, об этом файле. Во-первых, «#meta-image-button» должно соответствовать идентификатору кнопки, которую мы разместили в нашем meta box. Во-вторых, строка “library: { type: ‘image’ }” задает медиазагружчику отображать только изображения. И, наконец, «#meta-image» должен совпадать с ID поля ввода текста, который мы разместили в нашем meta box для хранения URL изображения.

Теперь, когда наш Javascript готов, мы хотим добавить еще одну функцию в файл custom-meta-box-template.php, который будет загружать его вместе с тем, что мы загрузим в медиа-загрузчик. Мы можем сделать это, добавив следующий код в файл custom-meta-box-template.php:

/**
 * Loads the image management javascript
 */
function prfx_image_enqueue() {
    global $typenow;
    if( $typenow == 'post' ) {
        wp_enqueue_media();
 
        // Registers and enqueues the required javascript.
        wp_register_script( 'meta-box-image', plugin_dir_url( __FILE__ ) . 'meta-box-image.js', array( 'jquery' ) );
        wp_localize_script( 'meta-box-image', 'meta_image',
            array(
                'title' => __( 'Choose or Upload an Image', 'prfx-textdomain' ),
                'button' => __( 'Use this image', 'prfx-textdomain' ),
            )
        );
        wp_enqueue_script( 'meta-box-image' );
    }
}
add_action( 'admin_enqueue_scripts', 'prfx_image_enqueue' );

Так же, как мы это делали с выбором цвета, то эта функция проверяет, чтобы убедиться, что глобальная переменная $typenow установлена на «post», прежде чем продолжить. Затем она вызывает функцию wp_enqueue_media(), встроенную в WordPress, которая загружает все ресурсы, необходимые для управления медиа. Затем она регистрирует наш файл meta-box-image.js. Тем не менее, в отличие от выбора цвета, мы хотим передать в наш файла JavaScript несколько строк текста, один для использования в области заголовка в медиа-менеджер, а другой для кнопки загрузки изображения. Мы делаем это с помощью функции wp_localize_script().

Function: wp_localize_script( $handle, $object_name, $l10n )
$handle string Название скрипта, перед которым будут добавлены данные. Скрипт должен быть зарегистрирован заранее.
$object_name string Название Javascript объекта, который будет содержать данные. Название должно быть уникальным, чтобы не вызвать конфликтов с другими скриптами! В названии нельзя использовать тире (-), только латиницу, подчеркивание (_) или примерять метод «верблюжьегоРегстра» (CamelCase).
$l10n array Сами данные. Данные могут быть как в одномерном, так и в многомерном массиве.

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

Почти готово! Мы просто должны добавить последний небольшой фрагмент кода, который сохраняет URL изображения в базу данных. Этот код добавляется к функции prfx_save_meta() так же, как наши предыдущие поля ввода.

// Checks for input and saves if needed
if( isset( $_POST[ 'meta-image' ] ) ) {
    update_post_meta( $post_id, 'meta-image', $_POST[ 'meta-image' ] );
}

… и вот как интегрировать медиа менеджер WordPress в пользовательский meta box.

9.3 Загрузчик файлов

Код для загрузки изображения на самом деле является загрузчиком файлов с фильтром, чтобы отобразить только изображения в менеджере медиа. Создание файла загрузчика вместо загрузки изображений делается при помощи всего пары небольших модификаций. Во-первых, нам нужно удалить следующую строку из мета-image.js, который мы создали для пользователя изображения:.

library: { type: 'image' }

Теперь все типы файлов в менеджере медиа будут видны.

Во-вторых, мы хотим изменить название и текст кнопки в скрипте обработчике:

'title' => 'Choose or Upload a File',
'button' => 'Use this file',

Вы можете думать, «А что, если я хочу использовать одновременно загрузчик изображений с загрузчиком файлов в том же мета-поле (или даже загрузки нескольких изображений в одном мета окне)?» Это хороший вопрос, но я не собираюсь описывать это шаг за шагом здесь. Давайте просто скажем, что один из способов вы могли бы сделать, это лучше чем дублировать весь код, используемый для создания загрузки изображения с маленькими изменениями, такими как идентификаторы полей формы, данные о локализации, а также имя файла JavaScript. Я не говорю, что это единственный способ, но это один из способов.

Источник: THEME FOUNDATION

Поделиться:

Отправить ответ

avatar
  Subscribe  
Notify of