Давным-давно я уже писал о том как добавить в админку WordPress произвольное поле с возможностью загрузки файлов, но код из той статьи все это время меня смущал. Дело в том что прошлый раз я описал не лучшую реализацию загрузчика да и код мягко говоря грязноват, поэтому я решил написать тоже самое но более красиво и удобно поэтому я изучил вопрос глубже и выяснилось вот что: в админке на странице редактирования поста в javascript определен глобальный объект wp который содержит все что нужно для реализации данной функциональности.
Содержимое объекта с комментариями можно посмотреть в файле wp-includes/js/media-editor.js.
Посмотрев на все это я написал кусочек JavaScript который по всем параметрам сильно лучше аналогичного из прошлого поста, код реше ряда недостатков, нет прямых обращений к window, url параметров и ссылок прописанных прямо в коде.
Благодаря всему этому стало возможным запихнуть весь функционал фронтенда загрузчика а один обработчик onclick.
jQuery(function ($) { $("[href='#al_uploader_anchor']").on('click',function () { var elem = $(this); var img_wrap = $('.al_uploader-img-wrap'); var input = img_wrap.parent().find('input'); wp.media.editor.send.attachment = function (info, file) { var id = file.id; var url = file.url; img_wrap.find('img').remove(); img_wrap.append("<img src='" + url + "' style='display: block; width:100%; height: auto' >"); input.attr('value', id); elem.text(elem.attr('data-text')); }; wp.media.editor.open(this); return false; }); });
Здесь аргумент file , callback-функции содержит всю необходимую информацию о медиафайле включая его id который я и буду использовать в дальнейшем на бекенде, а вот кстати и его код:
class al_uploader { private $this_file; private $form_attr_name; private $post_types = array(); function __construct($file) { $this->post_types = apply_filters('al_uploader_post_types', array('post')); $this->this_file = $file; $this->form_attr_name = '_al_uploader_upload_field_'; add_action('admin_init', array($this, 'add_extra_fields'), 1); add_action('save_post', array($this, 'fields_update'), 0); add_action('admin_enqueue_scripts', array($this, 'upload_script')); } function upload_script() { if (!did_action('wp_enqueue_media')) { wp_enqueue_media(); } wp_enqueue_script('al_uploader_scripts', plugin_dir_url($this->this_file) . 'admin/js/scripts.js', array('jquery'), null, false); } function add_extra_fields() { add_meta_box('al_uploader', 'Загрузка файла', array($this, 'fields_html'), array('post'), 'side', 'low'); } function fields_html($post) { $field_name='al_thumbnail'; $post_data = get_post_meta($post->ID, 'al_thumbnail', true); ?> <?php if ($post_data == '') { echo "<a href='#al_uploader_anchor' data-text='Задать другую миниатюру'>Задать миниатюру</a>"; } else { echo "<a href='#al_uploader_anchor' data-text='Задать миниатюру'>Задать новую миниатюру</a>"; } ?> <input type="text" name="<?php echo $this->form_attr_name; ?>[<?php echo $field_name;?>]" value="<?php echo $post_data[$field_name]; ?>" style="display: none"/> <span class="al_uploader-img-wrap"> <?php if ($post_data !== '') { $src = wp_get_attachment_image_url($post_data, array(300, 300)); echo "<img src='{$src}' style='display: block; width: 100%; height: auto'>"; } ?> </span> <input type="hidden" name="<?php echo $this->form_attr_name; ?>_fields_nonce" value="<?php echo wp_create_nonce($this->this_file); ?>"/> <?php } function fields_update($post_id) { if (!wp_verify_nonce($_POST[$this->form_attr_name . '_fields_nonce'], $this->this_file)) { return false; } if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return false; } if (!current_user_can('edit_post', $post_id)) { return false; } if (!isset($_POST[$this->form_attr_name])) { return false; }; $items = array_map('trim', $_POST[$this->form_attr_name]); foreach ($items as $key=>$val){ update_post_meta($post_id, $key, $val); } return $post_id; } } function al_uploader_init() { new al_uploader(__FILE__); } add_action('plugins_loaded', 'al_uploader_init');
тут все просто , сначала в методе upload_script подключаем необходимые JavaScript файлы, после с помощью add_extra_fields и add_meta_box создаем стандартный метабокс, метод fields_html добавляет разметку метабокса, и в конце обработчик POST запросов fields_update стандартным для меня способом который я когда то видел на сайте wp-kama.ru (кстати рекомендую почитать этот сайт).
Собственно всё, плагин готов исходники я выложил на Github. Теперь его можно установить, добавить изображение к какому либо посту и после сохранения можно будет получить его как обычное произвольное поле WordPress
get_post_meta($post_id, 'al_thumbnail', true );
После чего его можно будет использовать например в коде шаблонов либо в любом другом месте на свое усмотрение.
Так же в конструктор класса плагина я добавил фильтр al_uploader_post_types что бы можно было при необходимости добавить метабок плагина к любому типу поста, а не только типа post
add_filter('al_uploader_post_types', function($arr){ $arr[]='page'; return $arr; });
Прмерно вот так.
Ошибка в заголовке «чатсть 2»
Спасибо я исправил