В следующих двух статьях мы рассмотрим, как мы можем использовать API WordPress для определения наших собственных пользовательских мета-блоков для присоединения документа (такого как PDF) к нашим страницам WordPress. Мы также рассмотрим, как правильно удалять файлы, если мы решим удалить их из наших сообщений.
Несколько месяцев назад Кристофер Дэвис продемонстрировал, как создавать собственные WordPress записи / мета-боксы (http://wp.tutsplus.com/tutorials/plugins/how-to-create-custom-wordpress-writemeta-boxes/). Как упоминалось в его статье, пользовательские мета-блоки являются невероятно мощными функциями, которые позволяют нам добавлять различные фрагменты дополнительной информации в наши посты и страницы WordPress.
Конечно, мы не ограничены текстом или параметрами, такими как переключатели или флажки. Мы также можем прикреплять изображения и файлы к сообщениям, страницам и другим типам сообщений, используя преимущества пользовательских мета-блоков; однако работа с типами файлов требует немного больше кода для правильной обработки загрузки и удаления файла.
Прежде чем начать, важно отметить, что эта серия предполагает, что мы работаем с темой Twentyeleven . Несмотря на то, что код будет работать с любой темой WordPress, это гарантирует, что мы все работаем с одной и той же кодовой базой, и должно упростить выполнение этого руководства.
Определение пользовательского мета-бокса
Во-первых, давайте создадим мета-поле поста. В частности, мета-бокс должен …
- Быть доступным как на постах, так и на страницах
- Появляются рядом с редактором постов
- Принять входной файл
На этом этапе найдите functions.php в корне каталога тем Twentyeleven. Мы будем вносить все наши изменения в конец файла. Мы начнем с определения функции с именем add_custom_meta_boxes, и она будет зарегистрирована с помощью ловушки add_meta_boxes.
1
2
3
4
|
function add_custom_meta_boxes() {
} // end add_custom_meta_boxes
add_action(‘add_meta_boxes’, ‘add_custom_meta_boxes’);
|
Далее давайте определим наш собственный мета-блок. Сначала мы напишем код, после которого я объясню, что делает код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
function add_custom_meta_boxes() {
// Define the custom attachment for posts
add_meta_box(
‘wp_custom_attachment’,
‘Custom Attachment’,
‘wp_custom_attachment’,
‘post’,
‘side’
);
// Define the custom attachment for pages
add_meta_box(
‘wp_custom_attachment’,
‘Custom Attachment’,
‘wp_custom_attachment’,
‘page’,
‘side’
);
} // end add_custom_meta_boxes
add_action(‘add_meta_boxes’, ‘add_custom_meta_boxes’);
|
Обратите внимание, что следующие два вызова add_meta_box практически идентичны.
- Первый параметр — это идентификатор мета-блока. Это используется при сохранении значения.
- Вторым параметром является метка. Это значение отображается в заголовке над мета-окном записи
- Третье значение — это функция обратного вызова, которая используется для определения разметки, отображаемой в мета-блоке. Мы вернемся к этому на мгновение.
- Четвертое значение сообщает WordPress тип сообщения, в котором должен отображаться этот пользовательский мета-блок. Поскольку мы хотим, чтобы это было как на постах, так и на страницах, мы определили это дважды.
- Последний параметр определяет, где мы хотим, чтобы мета-поле появилось. Это может быть либо сторона, продвинутый, либо нормальный. Мы выбрали сторону, чтобы она отображалась рядом с редактором постов.
Настройка обратного вызова
На этом этапе пользовательский метабокс ничего не делает. На самом деле, он даже ничего не отображает:
Это связано с тем, что мы не определили функцию обратного вызова, которая генерирует разметку для мета-блока. Для этого нам нужно определить функцию с именем, которое мы перечислили выше. В частности: ‘wp_custom_attachment.’
Входные данные должны принимать PDF, поэтому мы дадим краткое описание и соответствующий элемент ввода для приема файлов:
01
02
03
04
05
06
07
08
09
10
11
12
|
function wp_custom_attachment() {
wp_nonce_field(plugin_basename(__FILE__), ‘wp_custom_attachment_nonce’);
$html = ‘<p class=»description»>’;
$html .= ‘Upload your PDF here.’;
$html .= ‘</p>’;
$html .= ‘<input type=»file» id=»wp_custom_attachment» name=»wp_custom_attachment» value=»» size=»25″ />’;
echo $html;
} // end wp_custom_attachment
|
Первая строка кода определяет одноразовое значение для правильной проверки и защиты нашей загрузки.
Далее мы просто устанавливаем разметку для отображения поля ввода.
На данный момент у нас есть пользовательский метабокс, который выглядит прилично, но на самом деле не работает.
Сохранение файла
Теперь мы готовы сохранить файл. Во-первых, нам нужно создать функцию, которая подключается к хуку save_post. Давайте определим это сейчас:
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 save_custom_meta_data($id) {
/* — security verification — */
if(!wp_verify_nonce($_POST[‘wp_custom_attachment_nonce’], plugin_basename(__FILE__))) {
return $id;
} // end if
if(defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) {
return $id;
} // end if
if(‘page’ == $_POST[‘post_type’]) {
if(!current_user_can(‘edit_page’, $id)) {
return $id;
} // end if
} else {
if(!current_user_can(‘edit_page’, $id)) {
return $id;
} // end if
} // end if
/* — end security verification — */
} // end save_custom_meta_data
add_action(‘save_post’, ‘save_custom_meta_data’);
|
Хотя эта функция на самом деле не сохраняет значение — по крайней мере, пока — она включает в себя немного кода, который гарантирует, что мы готовы сохранить файл. В частности, функция обеспечивает наличие ожидаемого одноразового значения, отсутствие автоматического сохранения и наличие у пользователя, пытающегося сохранить данные, разрешений для этого.
Теперь мы готовы начать проверку и сохранение файла. Когда дело доходит до сохранения пользовательских метаданных на основе файлов, необходимо ввести дополнительный код, чтобы правильно обрабатывать особенности загрузки файлов. Сначала мы определим код, а затем объясним. Функция должна выглядеть так:
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
|
function save_custom_meta_data($id) {
/* — security verification — */
if(!wp_verify_nonce($_POST[‘wp_custom_attachment_nonce’], plugin_basename(__FILE__))) {
return $id;
} // end if
if(defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE) {
return $id;
} // end if
if(‘page’ == $_POST[‘post_type’]) {
if(!current_user_can(‘edit_page’, $id)) {
return $id;
} // end if
} else {
if(!current_user_can(‘edit_page’, $id)) {
return $id;
} // end if
} // end if
/* — end security verification — */
// Make sure the file array isn’t empty
if(!empty($_FILES[‘wp_custom_attachment’][‘name’])) {
// Setup the array of supported file types.
$supported_types = array(‘application/pdf’);
// Get the file type of the upload
$arr_file_type = wp_check_filetype(basename($_FILES[‘wp_custom_attachment’][‘name’]));
$uploaded_type = $arr_file_type[‘type’];
// Check if the type is supported.
if(in_array($uploaded_type, $supported_types)) {
// Use the WordPress API to upload the file
$upload = wp_upload_bits($_FILES[‘wp_custom_attachment’][‘name’], null, file_get_contents($_FILES[‘wp_custom_attachment’][‘tmp_name’]));
if(isset($upload[‘error’]) && $upload[‘error’] != 0) {
wp_die(‘There was an error uploading your file. The error is: ‘ . $upload[‘error’]);
} else {
add_post_meta($id, ‘wp_custom_attachment’, $upload);
update_post_meta($id, ‘wp_custom_attachment’, $upload);
} // end if/else
} else {
wp_die(«The file type that you’ve uploaded is not a PDF.»);
} // end if/else
} // end if
} // end save_custom_meta_data
add_action(‘save_post’, ‘save_custom_meta_data’);
|
Новый блок кода делает несколько вещей. Комментарии были предоставлены для ясности, но вот что происходит:
- Сначала убедитесь, что массив файлов не пуст
- Затем мы устанавливаем массив для поддерживаемых типов файлов и проверяем, что загруженный файл относится к этому типу.
- Далее мы используем wp_upload_bits для копирования файла на сервер
- Наконец, если будут какие-либо ошибки, мы остановим выполнение и покажем их пользователю.
Примечание о wp_upload_bits (http://codex.wordpress.org/Function_Reference/wp_upload_bits). Эта функция является альтернативой wp_handle_upload (http://codex.wordpress.org/Function_Reference/wp_handle_upload). По моему опыту, wp_handle_upload привел к некоторым проблемам с определенными конфигурациями сервера, так что он дает ложный отрицательный результат. Под этим я подразумеваю, что он утверждает, что у него есть проблема с загрузкой файла, когда на самом деле файл был загружен.
Связывание файла
На данный момент мы должны быть готовы предоставить ссылку на файл на наших сообщениях и наших страницах. В каталоге Twentyeleven Theme найдите два файла: single.php и page.php. Каждый файл содержит строку кода, которая выглядит следующим образом:
1
|
get_template_part( ‘content’, ‘single’ );
|
Чуть ниже этой строки нам потребуется запросить мета-информацию о пользовательских записях, выполнив это:
1
|
echo get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);
|
В частности, эта функция запрашивает метаданные записи, идентифицированные как «wp_custom_attachment», связанные с этим идентификатором записи. Ясно, верно? Последний параметр сообщает WordPress, что мы хотим вернуть результат в строковом формате (альтернатива — в формате массива, и это выходит за рамки этого урока).
Последний блок кода должен выглядеть так:
1
|
get_template_part( ‘content’, ‘single’ );
|
1
|
echo get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);
|
Теперь попробуйте загрузить файл для страницы или сообщения. Загрузите пост и страницу в вашем браузере. Если все прошло правильно, вы заметите, что … упс … у вас нет пути к файлу.
Обновить форму сообщения
Проблема заключается в том, что по умолчанию элемент формы, используемый для сохранения всей информации о публикации и связанных с ней данных, не принимает типы файлов. Это можно исправить, добавив еще одну функцию, которая подключается к жизненному циклу страницы WordPress:
1
2
3
4
|
function update_edit_form() {
echo ‘ enctype=»multipart/form-data»‘;
} // end update_edit_form
add_action(‘post_edit_form_tag’, ‘update_edit_form’);
|
Это добавит атрибут enctype к элементу формы редактора сообщений, чтобы загрузка файлов не поддерживалась.
Теперь давайте попробуем загрузить файл еще раз. Найдите свое сообщение или страницу в пользовательском мета-поле и попробуйте загрузить PDF. Если все идет хорошо, вы сможете перейти к записи и / или странице и увидеть URL-адрес файла.
Связывая это
Последний шаг самый простой. Затем вернитесь к файлам single.php и page.php и оберните вызов пользовательского запроса метаданных в привязку так, чтобы он выглядел следующим образом:
1
2
|
<?php get_template_part( ‘content’, ‘single’ );
<?php $img = get_post_meta(get_the_ID(), ‘wp_custom_attachment’, true);
|
1
2
3
|
<a href=»<?php echo $img[‘url’]; ?>»>
Download PDF Here
</a>
|
К этому моменту вы сможете прикрепить пользовательский PDF-файл к своей странице, и в нижней части содержимого страницы появится ссылка с ссылкой для загрузки. В следующем посте мы рассмотрим, как мы можем предоставить более качественные стили для привязки загрузки, а также удалим файл со страницы с помощью API WordPress.
А пока попробуйте поэкспериментировать с настройкой метабокса еще дальше. Например, попытайтесь включить пользовательскую метку для предоставления содержимого для ссылки.