Добавление загрузчика изображений в метабокс и на страницу настроек WordPress
Нередко возникает необходимость создать интуитивный интерфейс для клиентов, позволяющий без проблем загружать изображения в настройки поста или в настройки всего сайта в целом. На своих сайтах мы, разработчики, можем с легкостью вставить URL предварительно загруженного изображения в произвольное поле поста, а затем использовать это значение в коде (конечно, можно научить клиента такой процедуре, но это будет непрофессионально).
Итак, что в итоге у нас получится. Во-первых, вот так будет выглядеть поле для загрузки изображения (само собой, вы можете оформить его и по-другому):

При нажатии на кнопку «Загрузить» будет открываться всплывающее окно загрузчика медиафайлов WordPress:

Окей, выбираем картинку из медиатеки или загружаем новую и нажимаем кнопу «Вставить в запись». В итоге:

Вот и всё, осталось только сохранить пост.
Весь процесс добавления такого загрузчика изображений можно разделить на три шага, рассмотрим каждый шаг по отдельности, а затем перейдем к примерам.
Шаг 1. Код jQuery
Хочу обратить ваше внимание, что данный jQuery-код будет отлично работать только с тем кодом HTML, который предоставлен в шаге 3. Поэтому, если вы не разбираетесь в jQuery, старайтесь в нем ничего не менять, не переставлять элементы местами и т.д.
Что делать с этим кодом? Создайте какой-нибудь файл с расширением .js, затем залейте его в папку с вашей темой WordPress. Я например создал файл admin.js
.
Код можете скопировать как есть, он полностью рабочий и не требует какой-либо настройки.
jQuery(function($){ /* * действие при нажатии на кнопку загрузки изображения * вы также можете привязать это действие к клику по самому изображению */ $('.upload_image_button').click(function(){ var send_attachment_bkp = wp.media.editor.send.attachment; var button = $(this); wp.media.editor.send.attachment = function(props, attachment) { $(button).parent().prev().attr('src', attachment.url); $(button).prev().val(attachment.id); wp.media.editor.send.attachment = send_attachment_bkp; } wp.media.editor.open(button); return false; }); /* * удаляем значение произвольного поля * если быть точным, то мы просто удаляем value у input type="hidden" */ $('.remove_image_button').click(function(){ var r = confirm("Уверены?"); if (r == true) { var src = $(this).parent().prev().attr('data-src'); $(this).parent().prev().attr('src', src); $(this).prev().prev().val(''); } return false; }); }); |
Шаг 2. Подключаем скрипты в админку через wp_enqueue_script() и wp_enqueue_media()
Если на моём блоге вы совсем недавно и еще не знаете про правильное подключение JavaScript и CSS в WordPress, можете сперва почитать про wp_enqueue_script(), wp_enqueue_style() и wp_enqueue_media() или же можете сразу вставить следующий код в ваш файл темы functions.php
:
1 2 3 4 5 6 7 8 9 10 11 12 | function true_include_myuploadscript() { // у вас в админке уже должен быть подключен jQuery, если нет - раскомментируйте следующую строку: // wp_enqueue_script('jquery'); // дальше у нас идут скрипты и стили загрузчика изображений WordPress if ( ! did_action( 'wp_enqueue_media' ) ) { wp_enqueue_media(); } // само собой - меняем admin.js на название своего файла wp_enqueue_script( 'myuploadscript', get_stylesheet_directory_uri() . '/admin.js', array('jquery'), null, false ); } add_action( 'admin_enqueue_scripts', 'true_include_myuploadscript' ); |
Это универсальный код, просто вставьте его и он просто будет работать. Однако, если вы будете использовать загрузчик на страницах редактирования записей WordPress — вы можете спокойно удалить строки с 5й по 7ю, т. к. там загрузчик уже подключен.
Шаг 3. PHP-функция добавления полей в форму
Эта функция в первозданном виде тоже отправляется в файл functions.php
, единственное только вы можете поменять URL изображения, которое будет отображаться по умолчанию (вторая строка, переменная $default
).
function true_image_uploader_field( $name, $value = '', $w = 115, $h = 90) { $default = get_stylesheet_directory_uri() . '/img/no-image.png'; if( $value ) { $image_attributes = wp_get_attachment_image_src( $value, array($w, $h) ); $src = $image_attributes[0]; } else { $src = $default; } echo ' <div> <img data-src="' . $default . '" src="' . $src . '" width="' . $w . 'px" height="' . $h . 'px" /> <div> <input type="hidden" name="' . $name . '" id="' . $name . '" value="' . $value . '" /> <button type="submit" class="upload_image_button button">Загрузить</button> <button type="submit" class="remove_image_button button">×</button> </div> </div> '; } |
Готово! Функционал загрузчика добавлен. Теперь только осталось задействовать его в метабоксе или на странице настроек (в зависимости от того, какая задача перед вами стоит).
Использование в метабоксах
Код добавления метабокса — я максимально упростил его, для того, чтобы была понятна суть, также вы можете более подробно ознакомиться со всеми способами добавления метабоксов в WordPress.
Прежде, чем использовать представленный ниже код, убедитесь, что у вас выполнены все шаги.
В принципе и этот код вы можете вставить в functions.php
, ничего не меняя, в результате у вас должен будет появиться метабокс с загрузчиком изображений на страницах редактирования записей.
/* * Добавляем метабокс */ function true_meta_boxes_u() { add_meta_box('truediv', 'Настройки', 'true_print_box_u', 'post', 'normal', 'high'); } add_action( 'admin_menu', 'true_meta_boxes_u' ); /* * Заполняем метабокс */ function true_print_box_u($post) { if( function_exists( 'true_image_uploader_field' ) ) { true_image_uploader_field( 'uploader_custom', get_post_meta($post->ID, 'uploader_custom',true) ); } } /* * Сохраняем данные произвольного поля */ function true_save_box_data_u( $post_id ) { if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; update_post_meta( $post_id, 'uploader_custom', $_POST['uploader_custom']); return $post_id; } add_action('save_post', 'true_save_box_data_u'); |
Использование на странице настроек
Не уверен, что это самый оптимальный способ добавления страниц настроек, знаю только одно — он полностью рабочий. Как и в случае с метабоксами, добавляем код в ваш functions.php
.
<?php function true_add_options_page_u() { if ( isset( $_GET['page'] ) && $_GET['page'] == 'uplsettings' ) { if ( isset( $_REQUEST['action'] ) && 'save' == $_REQUEST['action'] ) { update_option('uploader_custom', $_REQUEST[ 'uploader_custom' ]); header("Location: ". site_url() ."/wp-admin/options-general.php?page=uplsettings&saved=true"); die; } } add_submenu_page('options-general.php','Дополнительные настройки','Настройки','edit_posts', 'uplsettings', 'true_print_options_u'); } function true_print_options_u() { if ( isset( $_REQUEST['saved'] ) ){ echo '<div class="updated"><p>Сохранено.</p></div>'; } ?><div class="wrap"> <form method="post"> <?php if( function_exists( 'true_image_uploader_field' ) ) { true_image_uploader_field('uploader_custom', get_option('uploader_custom')); } ?><p class="submit"> <input name="save" type="submit" class="button-primary" value="Сохранить изменения" /> <input type="hidden" name="action" value="save" /> </p> </form> </div><?php } add_action('admin_menu', 'true_add_options_page_u'); |
Если у вас возникнут какие-то проблемы с кодом или появятся предложения по его доработке, пожалуйста, оставьте свой комментарий ниже.
Хорошая статья, но вот админка реально устаревшего типа, лучше бы под стандартное API настроек подточили.
Больше всего интересовал сам вызов медиа загрузчика) Спасибо!
Относительно последнего примера — да, я так и написал в посту, над будет доработать 🙂
Классно все, но вопрос такой: как теперь вставить картинку в single? какой командой?
Как обычно, через редактор.
get_option('uploader_custom')
Аффигенно то что надо автору респект!)
Рад помочь 🙂
А как добавить 2-ю картинку, 3 и т.д
Заранее благодарна..
Ну в заполнении метабокса это делается так:
И в функции сохранения не забудьте указать:
Спасибо все работает 😀
Пожалуйста 😀
Спасибо за статью! Очень сложно найти инф по использованию стандартного загрузчика.
Пытаюсь переделать пример под свою задачу - прикрепление файлов (инструкций) пользователями к товарам. Т.е. хочу запустить стандартный загрузчик и получить от него ссылку на загруженный файл, и больше ничего. Возможно ли это?
Пожалуйста 🙂 если я вас правильно понял, то да.
Вызываю в теме echo get_option('uploader_custom') и мне выдает числовое значение, копировал все по 10 раз. все пути перепроверил по 50 раз, все правильно, но изображение я вывести не могу
Чтобы заработало, нужно:
- код jQuery из шага 1. Он запускает аплодер вордпресса по клику и получает выбранный файл (в function(props, attachment) {...). Можно написать туда свой код. Аплодер возвращает только 1 файл, хотя выделить в нем можно несколько.
- правильно подключить скрипты в шаге 2 -
admin_enqueue_scripts - только для админки
wp_enqueue_scripts - для внешней части сайта
login_enqueue_scripts - для страницы входа
Добрый день. Не подскажете как вывести картинку в пост.
Пробовал
Он выводит то-ли ID записи то-ли что, вообщем цифры.
Посмотрел в админке значения поле - uploader_custom, те-же цифры что и выводятся.
Заранее благодарен..
Добрый день!
Можете использовать одну из этих функций.
Не могу понять как вывести теперь эти картинки на странице? проовал использовать функции которые вы предложили ничего не получается
Какие пробовали?
Спасибо большое! Работает)
Со знанием PHP у меня не очень.. Так что Как то сделал, но при нажатии кнопки удалить, картинка сразу не удаляется, надо обновить пост тогда картинки не станет. А так все работает, выбираешь картинку (в поле uploader_custom - записывается url картинки). и миниатюра вместо картинки по умолчанию встает как положено. Прошу подправить код.
Заранее благодарен.
В первом листинге кода вместо button должен быть класс или ID элементов.
Smile привет, нашел решение. В первом листинге кода оставляешь все как есть.
Дальше переходишь в файл functions.php
Ищи учаток кода:
И меняй его как у меня.. все работает))
Замечательный мануал, спасибо.
Но все же еще остался не раскрытым вопрос мультивыбора.
В медаизагрузчике есть возможность выбирать сразу несколько файлов.
Как получить в JS все выбранные объекты?
Действительно тема в нете не особо широко освещена, видимо, потому что это уже глубоко узкоспециальный материал 🙂 но все же, мне интересно как организовать мультивыбор, но полчаса поиска не дали результата...
Есть вот такой вариант, не тестировал правда:
Спасибо Вам огромное!
Добрый день, подскажите в какую сторону капать если мне нужно что бы после того как пользователь выбрал картинку появилась еще одна пуская картинка или же был некий плюсик на который когда я клацаю добавляется еще одна картинка.
Я конечно понимаю что этот пример возможно не подходит для моей ситуации но может вы подскажите хоть что то) а то плагины ставить не хочу
Добрый день!
Используйте
after()
для вставки этого плюсика иlive('click', )
для нажатия на него.Вот про это было бы очень интересно почитать. Как твой стандартный класс для метабоксов (https://misha.blog/blog/wordpress/meta-boxes.html) сделать с динамическим добавлением новых произвольных полей, с одним ключом, но разными значениями.
Или может уже есть у тебя статья, ткни в меня ссылкой)).
Сейчас новый класс пишу, может в январе уже опубликую его:)
В js консоли Uncaught TypeError: Cannot read property 'value' of null, версия WP 4.1.1
Спасибо. Я гляну, в чем проблема.
Такая же ошибка и у меня в консоли.. Не подскажите, в чём дело и как поправить? Спасибо.
проблема все еще актуальна
Михаил!Добрый день Михаил! Воспользовался вашим кодом – всё работает,
Но получаю изображение размером 150х150, а нужно в полный размер.
Подскажите пожалуйста, как получить картинку в полный размер.
Разобрался сам 🙂
$attributes = wp_get_attachment_image_src( $attachment_id, 'full' );
А не могли бы вы подсказать, как реализовать подобный загрузчик в плагине?
Сейчас делаю плагин, в одном из пунктов в котором человек должен выбрать\загрузить картинку и хотелось бы все реализовать родными ресурсами WP.
Правда, отличие в том, что нужно после того как человек загрузил картинку получить ссылку на неё, которая дальше будет вносится в БД плагина и использоваться на сайте.
Ну тут сходу ничего не ответить — нужно писать код. Если у вас будут более конкретные вопросы, постараюсь помочь.
Добрый день! Подскажите, как сделать чтобы эту форму мог видеть только админ сайта? Чтобы редакторы и авторы ее не видели.
Добрый день!
Спасибо очень выручил ваш метод!
А как эту форму добавить вот сюда https://misha.blog/blog/wordpress/option-pages.html
никак не могу понять как его добавть в секцию, например section_3 и использовать в дальнейшем.
Ну в очень общих чертах:
Можно мне объяснить что это или что оно делает wp.media.editor.send.attachment?
Делает AJAX-запрос и получает данные изображения.
Подскажите где можно об это почитать более подробно
Поищите по запросу API media editor WordPress.
Успешно портировал ваш код для того что бы создать Виджет.
Всё отлично работает только через какое то время на странице виджетов в консоли получаю следующую ошибку: TypeError: document.getElementById(...) is null
Она не сильно мешает, но правда при любом действии с любым Виджетом, происходит обновление страницы. Не могли бы вы подсказать с чем это связано ? С этой ошибкой или ещё как ?
Спасибо.
P.S: Могу скинуть код Виджета, вы бы могли бы его добавить в статью.
Сорри за задержку с ответом — был в отъезде.
Проблема явно в JavaScript. Вам нужно искать, где у вас пустое значение
document.getElementById(...)
.Вот что записывает скрипт: http://SSMaker.ru/2b77a594/
И? 🙂 Вижу название произвольного поля и ID аттачмента.
Для всех постом просто записывает "69" и все. не url на картинку, не чего вообще
Тут нужно смотреть код и разбираться, сходу не скажу.
Очень интересная и полезная статья. Попытался сделать добавление через плагин. Не подскажите почему, не отображается список файлов в библиотеке и не могу ничего загрузить.
В функции true_include_myuploadscript() переделал под плагин таким образом
Все скрипты проверяли? 404 нет? порядок верный?
да, все правильно. Сегодня утром зашел, поменял кодировку и все начало работать. Спасибо))
Как сделать чтобы в значении «uploader_custom» прописывался не id картинки а её url?
Спасибо!
ответ нашел