Статьи

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

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


Обе эти ловушки существуют со времен WordPress 2.5 и применяются в wp-admin / includes / media.php , но остаются недостаточно используемыми в сообществе, скорее всего, потому что они недокументированы в Кодексе. Ниже показано, где хуки применяются в основном коде, давая нам знать, что будет передано функциям, которые мы добавляем в каждый хук.

1
2
3
4
5
function get_attachment_fields_to_edit($post, $errors = null) {
    // …
    $form_fields = apply_filters(«attachment_fields_to_edit», $form_fields, $post);
    // …
}
  • $ form_fields — это специальный массив, который будет подробно описан ниже.
  • $ post — это вложение как объект (вложения рассматриваются как объекты post в WordPress).
1
2
3
4
5
function media_upload_form_handler() {
    // …
    $post = apply_filters(«attachment_fields_to_save», $post, $attachment);
    // …
}
  • $ post — это вложение в виде массива (вложения рассматриваются как объекты post в WordPress).
  • $ attachment является частью вложения формы $ _POST, которая будет включать в себя настройку полей через ловушку attachment_fields_to_edit .

Примечание. Будьте осторожны в своем коде, поскольку $ post отправляется одной функции как объекту, а другой — как массиву .

Добавляемые новые поля будут сохранены как мета-записи, как и раздел пользовательских полей на экране редактирования пост / страница. Поля с префиксом подчеркивания ( _my_custom_field ) не будут перечислены в раскрывающемся списке доступных настраиваемых полей на экране сообщения / страницы; все остальные существующие мета поля поста будут перечислены. Мы можем использовать эти знания, чтобы скрыть поля, которые мы добавляем в медиа-форму, так как они не имеют отношения к постам / страницам.

При выборе ключа массива $ form_fields для использования в новом поле необходимо учитывать аналогичное правило. Здесь, если вы используете подчеркивание ( $ form_fields [‘_ my_custom_field’] ), ваше поле будет пропущено и не будет добавлено в форму.

Поэтому, чтобы показать наши поля в медиа-форме, но не перечислить их в выпадающем списке настраиваемых полей страницы / публикации, мы должны объединить оба метода. Это задействует функции редактирования и сохранения, которые мы будем создавать. Для хука ‘ attachment_fields_to_edit ‘ мы установим ключи $ form_fields так , чтобы они не имели префиксов подчеркивания, а для хука ‘ attachment_fields_to_save ‘ мы добавим префиксы в наши поля с подчеркиванием перед сохранением их как post meta. Это обходной путь, который стоит сделать, чтобы не запутывать интерфейс наших пользователей ненужной информацией.


Ниже приведен пример того, как добавить свои собственные настраиваемые поля в форму вложения.

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
/**
 * Adding our custom fields to the $form_fields array
 *
 * @param array $form_fields
 * @param object $post
 * @return array
 */
function my_image_attachment_fields_to_edit($form_fields, $post) {
    // $form_fields is a special array of fields to include in the attachment form
    // $post is the attachment record in the database
    // $post->post_type == ‘attachment’
    // (attachments are treated as posts in WordPress)
     
    // add our custom field to the $form_fields array
    // input type=»text» name/id=»attachments[$attachment->ID][custom1]»
    $form_fields[«custom1»] = array(
        «label» => __(«Custom Text Field»),
        «input» => «text», // this is default if «input» is omitted
        «value» => get_post_meta($post->ID, «_custom1», true)
    );
    // if you will be adding error messages for your field,
    // then in order to not overwrite them, as they are pre-attached
    // to this array, you would need to set the field up like this:
    $form_fields[«custom1»][«label»] = __(«Custom Text Field»);
    $form_fields[«custom1»][«input»] = «text»;
    $form_fields[«custom1»][«value»] = get_post_meta($post->ID, «_custom1», true);
     
    return $form_fields;
}
// attach our function to the correct hook
add_filter(«attachment_fields_to_edit», «my_image_attachment_fields_to_edit», null, 2);

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

1
2
3
4
// input type=»text»
$form_fields[«custom1»][«label»] = __(«Custom Text Field»);
$form_fields[«custom1»][«input»] = «text»;
$form_fields[«custom1»][«value»] = get_post_meta($post->ID, «_custom1», true);

Оказывает в форме как:

1
2
3
4
// textarea
$form_fields[«custom2»][«label»] = __(«Custom Textarea»);
$form_fields[«custom2»][«input»] = «textarea»;
$form_fields[«custom2»][«value»] = get_post_meta($post->ID, «_custom2», true);

Оказывает в форме как:

Скрытые поля компилируются и выводятся в конце формы.

1
2
3
4
// input type=»hidden»
// no need for a label
$form_fields[«custom3»][«input»] = «hidden»;
$form_fields[«custom3»][«value»] = get_post_meta($post->ID, «_custom3», true);

Если вам нужен тип ввода, отличный от «text», «textarea» или «hidden», тогда используйте «html», который позволяет вам передавать свой собственный контент для использования в качестве элемента ввода по вашему выбору. Когда вы создаете свой собственный входной HTML, важно правильно установить атрибут ‘name’ для элемента, чтобы поле позже было передано нашей функции сохранения. Вы хотите что-то вроде этого: name = "attachments[$post->ID][my_custom_key]" .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
$form_fields[«custom4»][«label»] = __(«Custom Select»);
$form_fields[«custom4»][«input»] = «html»;
$form_fields[«custom4»][«html»] = «
<select name=’attachments[{$post->ID}][custom4]’ id=’attachments[{$post->ID}][custom4]’>
    <option value=’1′>Option 1</option>
    <option value=’2′>Option 2</option>
    <option value=’3′>Option 3</option>
</select>»;
 
// another example
$form_fields[«custom5»][«label»] = __(«Custom Checkbox»);
$form_fields[«custom5»][«input»] = «html»;
$form_fields[«custom5»][«html»] = «the html output goes here, like a checkbox:
<input type=’checkbox’ value=’1′
    name=’attachments[{$post->ID}][custom5]’
    id=’attachments[{$post->ID}][custom5]’ />»;

Оказывает в форме как:

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

help — Этот атрибут добавляет строку справки в ваше настраиваемое поле.

1
2
3
$form_fields[«custom6»][«label»] = __(«Custom Field with Helpful Text»);
$form_fields[«custom6»][«value»] = get_post_meta($post->ID, «_custom6», true);
$form_fields[«custom6»][«helps»] = «Put helpful text here.»;

Это выглядит в виде:

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

1
2
3
$form_fields[«custom7»][«label»] = __(«Required Field»);
$form_fields[«custom7»][«value»] = get_post_meta($post->ID, «_custom7», true);
$form_fields[«custom7»][«required»] = TRUE;

Оказывает в форме как:

extra_rows — Этот атрибут позволяет вам добавить массив строк сразу после вашего настраиваемого поля. Разметка для каждого элемента массива показана ниже: ключ массива станет классом td , а значение — содержимым:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
// extra_rows markup:
// <tr>
// <td></td>
// <td class=»{arrayItemKey}»>{arrayItemValue}</td>
// </tr>
$form_fields[«custom8»][«label»] = __(«Custom Field with Extra Rows»);
$form_fields[«custom8»][«value»] = get_post_meta($post->ID, «_custom8», true);
// extra_rows must be an associative array $cssClass => $content
$form_fields[«custom8»][«extra_rows»] = array(
    «cssClass1» => «If you need a few rows after your field…»,
    «cssClass2» => «…to maybe explain something or add some imagery?
            <img src='».get_bloginfo(«wpurl»).»/wp-admin/images/align-left.png’ />
            <img src='».get_bloginfo(«wpurl»).»/wp-admin/images/align-center.png’ />
            <img src='».get_bloginfo(«wpurl»).»/wp-admin/images/align-right.png’ />»,
);

Оказывает в форме как:

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

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

1
2
3
4
5
6
$form_fields[«custom8»][«tr»] = «
<tr id=’MySpecialRow’>
    <td colspan=’2′ style=’background:#000;color:#fff;’>
        Can do whatever you want, style it, add some fields, display a table of data…sky’s the limit
    </td>
</tr>»;

Оказывает в форме как:


Сохранение ваших пользовательских полей гораздо проще, чем добавление их в форму; просто проверьте, установлено ли ваше поле, и обновите его значение как post meta. Запомните, чтобы при сохранении префикс вашего поля подчеркивался, чтобы скрыть его на экране редактирования поста / страницы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
/**
 * @param array $post
 * @param array $attachment
 * @return array
 */
function my_image_attachment_fields_to_save($post, $attachment) {
    // $attachment part of the form $_POST ($_POST[attachments][postID])
    // $post attachments wp post array — will be saved after returned
    // $post[‘post_type’] == ‘attachment’
    if( isset($attachment[‘my_field’]) ){
        // update_post_meta(postID, meta_key, meta_value);
        update_post_meta($post[‘ID’], ‘_my_field’, $attachment[‘my_field’]);
    }
    return $post;
}

Вы также можете добавить сюда ошибки, которые будут автоматически отображаться под вашим полем в форме. Массив $post['errors'] объединяется с массивом $form_fields перед отправкой через ловушку attachment_fields_to_edit .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
/**
 * @param array $post
 * @param array $attachment
 * @return array
 */
function my_image_attachment_fields_to_save($post, $attachment) {
    if( isset($attachment[‘my_field’]) ){
        if( trim($attachment[‘my_field’]) == » ){
            // adding our custom error
            $post[‘errors’][‘my_field’][‘errors’][] = __(‘Error text here.’);
        }else{
            update_post_meta($post[‘ID’], ‘my_field’, $attachment[‘my_field’]);
        }
    }
    return $post;
}

Примечание по поводу пользовательских ошибок: в WordPress есть пара давних ошибок (начиная с версии 3.0-RC3), которые связаны с отображением пользовательских ошибок.

  1. Одно из них не позволит вашим пользовательским сообщениям об ошибках появиться на одной странице редактирования мультимедиа.
  2. Другая ошибка в модальном всплывающем окне для элементов мультимедиа, используемых на экране редактирования поста / страницы. Ошибки отображаются
    здесь проблема только в том, чтобы увидеть их. После сохранения вы автоматически переключаетесь на
    Вкладка «Галерея», где есть свернутый список медиа-элементов. Если вы нажмете «показать», чтобы открыть новый элемент,
    вы увидите ваши сообщения об ошибках в форме. Проблема в том, что если есть ошибки, то форма элементов должна
    быть открытым по умолчанию. В css есть ошибка, когда класс ‘startopen’ (который присутствует на элементе, если
    есть ошибки, чтобы показать) имеет значение ‘display: none’ в нескольких местах в основных таблицах стилей.

Я отправил исправления для обеих этих проблем ( # 13810 и # 13838 ), и мне сказали, что они должны быть рассмотрены и включены в версию 3.1. Поэтому пока не слишком полагайтесь на свои сообщения об ошибках, просто порадуйтесь, что вы знаете, как с ними работать, когда они станут более полезными в ближайшем будущем.


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

01
02
03
04
05
06
07
08
09
10
11
// for audio files
if( substr($post->post_mime_type, 0, 5) == ‘audio’ ){
    // add your custom fields for audio files
}
 
// OR for images on a specific page
 
$page_id = 5;
if( $post->post_parent == $page_id && substr($post->post_mime_type, 0, 5) == ‘image’ ){
    // add your image specific custom fields for this particular page
}

Если вы думаете о каких-либо умных способах использования пользовательских полей с вложениями, поделитесь им с нами в комментариях!