Статьи

Поддержка WordPress SVG: как включить SVG в WordPress

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

Кросс-браузерная поддержка теперь также является всеобъемлющей: все современные браузеры поддерживают SVG при использовании с тегом изображения или в CSS как часть свойства background .

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

Сегодняшний учебник будет посвящен тому, как мы можем добавить поддержку носителей SVG, а также улучшить обработку, обработку и отображение SVG в WordPress в целом.

Предыстория — Почему нет поддержки SVG в WordPress?

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

SVG не являются растровыми изображениями, как другие форматы (такие как png , jpg , gif ), они на самом деле являются векторами и поэтому могут потенциально использоваться для переноса вредоносного JavaScript. Есть замечательная статья Бьёрна Йохансена, в которой рассказывается, как все это работает. Суть в том, что в него можно вставить JavaScript, и он выполняется при отображении SVG.

Разработчики ядра WordPress обсуждают включение SVG в течение очень долгого времени (3-4 года), и основным камнем преткновения являются потенциальные угрозы безопасности, которые он может представлять. Диспетчер мультимедиа используется на нескольких уровнях: от администраторов сайтов до редакторов и участников. Это означает, что существует несколько групп, которые могут загружать (невольно или намеренно) вредоносные файлы SVG на сайт.

Скорее всего, какое-то время это не произойдет, и, к сожалению, это означает, что SVG не будет опцией загрузки по умолчанию в ближайшее время.

svg медиа-библиотека отклонить предупреждение

Добавление формата SVG в разрешенные типы файлов

К счастью, поскольку WordPress очень гибок, мы можем настроить типы файлов, которые можно загружать в медиа-библиотеку. Нам нужно только подключиться к фильтру upload_mimes и добавить нашу поддержку SVG. Вы можете добавить этот код в файл functions.php вашей дочерней темы или создать его как плагин.

 //add SVG to allowed file uploads function add_file_types_to_uploads($file_types){ $new_filetypes = array(); $new_filetypes['svg'] = 'image/svg+xml'; $file_types = array_merge($file_types, $new_filetypes ); return $file_types; } add_action('upload_mimes', 'add_file_types_to_uploads'); 

Мы подключаем массив разрешенных типов файлов и добавляем расширение SVG ( image/svg+xml ) в качестве допустимого типа файлов.

Это все, что нам нужно сделать, чтобы WordPress мог загружать эти изображения. Теперь, когда вы заходите в медиа-библиотеку, вы можете перетаскивать SVG-файлы прямо в библиотеку, и они будут отображаться в виде стандартного файла.

WordPress SVG библиотека

Улучшение отображения SVG в библиотеке мультимедиа

Поскольку SVG-файлы не являются типом файлов по умолчанию, их отображение и обработка предоставляются «как есть», что означает, что все они будут работать на панели администратора, но у вас не обязательно будет максимально упрощенный пользовательский интерфейс.

Одной из таких областей, где отсутствует оптимизация SVG, является «Grid View» библиотеки.

При просмотре SVG в этом представлении каждый SVG отображается как общий заполнитель, показывающий значок по умолчанию и имя файла (как видно на предыдущем изображении). Хотя это все еще работает, на самом деле это вам мало поможет, поскольку, если вы не запомните имена файлов ваших SVG, вы не узнаете, что есть что. То, что должно отображаться, это само изображение, а не заполнитель.

Это то, на что мы сейчас будем смотреть, оптимизируя «Grid», чтобы получить что-то более визуально полезное.

Обновление SVG вручную в виде сетки

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

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

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

Наблюдатели Мутации

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

Это идеальный вариант использования Mutation Observers

«Наблюдатели мутаций» предоставляют разработчикам возможность реагировать на изменения в DOM и получать список всех изменений (мутаций), которые произошли для его узлов. Эти обозреватели заменяют устаревшие mutation events и имеют довольно всестороннюю поддержку браузера, работая на всех современных системах, вплоть до IE11.

CSS-твик администратора для улучшения отображения SVG

Есть несколько мест, где нам нужно применить легкий стиль, чтобы наши SVG-изображения выглядели великолепно по всему бэкэнду WordPress. Единственное реальное примечание — это то, что в старых браузерах (IE8-IE10) SVG не любят изменять размеры и требуют заданного атрибута высоты и ширины при отображении в виде изображения. Для наших целей и для большинства браузеров этих CSS-настроек будет достаточно.

Основная проблема, с которой мы столкнемся, заключается в том, что SVG не присваиваются значения высоты или ширины, что приводит к их свертыванию (и становлению невидимым). Установка ширины SVG на 100%, и ее высота решит это.

Макет сетки мультимедийной библиотеки

Более новая сетка по умолчанию обеспечивает простой в использовании интерфейс для управления и просмотра ваших вложений. Хотя он великолепен и работает хорошо, он не очень хорошо демонстрирует ваши SVG, по умолчанию их отображает значок с именем файла.

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

Сложность в этом заключается в том, что библиотека создается динамически, а это означает, что нам нужно все настроить в JavaScript, чтобы все было так, как мы хотим. Это где наш Mutation Observer вступает в игру. Мы можем искать все недавно добавленные DOM-узлы, а затем проверять, являются ли они вложением, и можем ли мы управлять ими так, как нам хочется.

Наше решение включает использование JavaScript для обнаружения нашего вложения и передачу его идентификатора обратно в PHP, чтобы мы могли получить полный URL-адрес вложения. Чтобы это работало, нам нужно подключиться к функциональности WordPress AJAX и зарегистрировать пользовательскую функцию, например ниже.

 //call our function when initiated from JavaScript add_action('wp_AJAX_svg_get_attachment_url', 'get_attachment_url_media_library'); 

wp_AJAX_{name_of_action} используется для создания пользовательских вызовов AJAX. Это означает, что всякий раз, когда вызывается WordPress AJAX, он будет искать action с тем же именем, зарегистрированным в этом хуке. В нашем случае, когда мы позже вызовем нашу AJAX-функцию, мы svg_get_attachment_url действие, называемое svg_get_attachment_url , которое, в свою очередь, вызовет нашу функцию get_attachment_url_media_library .

Если вы впервые заглядываете в WordPress AJAX, тогда начните с чтения документации по Кодексу.

Наша функция вернуть URL-адрес вложения довольно проста:

 //called via AJAX. returns the full URL of a media attachment (SVG) function get_attachment_url_media_library(){ $url = ''; $attachmentID = isset($_REQUEST['attachmentID']) ? $_REQUEST['attachmentID'] : ''; if($attachmentID){ $url = wp_get_attachment_url($attachmentID); } echo $url; die(); } 

Теперь, когда у нас отсортированы элементы PHP, давайте перейдем к компоненту JavaScript и добавим следующее. Вам нужно будет добавить следующее в поставленный в очередь публичный скрипт, чтобы это работало.

 //create a mutation observer to look for added 'attachments' in the media uploader var observer = new MutationObserver(function(mutations){ // look through all mutations that just occured for (var i=0; i < mutations.length; i++){ // look through all added nodes of this mutation for (var j=0; j < mutations[i].addedNodes.length; j++){ //get the applicable element element = $(mutations[i].addedNodes[j]); //execute only if we have a class if(element.attr('class')){ elementClass = element.attr('class'); //find all 'attachments' if (element.attr('class').indexOf('attachment') != -1){ //find attachment inner (which contains subtype info) attachmentPreview = element.children('.attachment-preview'); if(attachmentPreview.length != 0){ //only run for SVG elements if(attachmentPreview.attr('class').indexOf('subtype-svg+xml') != -1){ //bind an inner function to element so we have access to it. var handler = function(element){ //do a WP AJAX call to get the URL $.AJAX({ url: AJAXurl, data: { 'action' : 'svg_get_attachment_url', 'attachmentID' : element.attr('data-id') }, success: function(data){ if(data){ //replace the default image with the SVG element.find('img').attr('src', data); element.find('.filename').text('SVG Image'); } } }); }(element); } } } } } } }); observer.observe(document.body, { childList: true, subtree: true }); 

Вот разбивка того, как все это работает:

  • Мы создаем новый ‘Mutation Observer’ и слушаем все изменения в элементе body. Мы ищем наши вложения, которые загружаются динамически (изначально при открытии библиотеки и, дополнительно, при прокрутке, чтобы загрузить больше).
  • Мы просматриваем все добавленные элементы DOM и присваиваем их нашему element , именно на этом элементе мы проведем наши сравнения, чтобы проверить, находим ли мы нужный элемент.
  • Мы проверяем, что у нашего элемента есть класс (как иногда мы перебираем стандартные текстовые элементы), и затем мы используем его класс, чтобы увидеть, есть ли у него имя класса attachment . Каждое из наших вложений будет иметь это, поэтому именно эти элементы мы ищем.
  • Как только мы находимся во вложении, мы делаем еще одну проверку, чтобы убедиться, что мы находимся на одном вложении (как иногда мы можем быть на других элементах, которые, так случается, связаны с вложениями, но не самих вложений), тогда поиск любые дети с классом 'attachment-preview сообщат нам, если мы на правильном пути.
  • Следующим шагом является проверка, есть ли у предварительного просмотра вложения класс subtype-svg+xml . Мы хотим активировать нашу функциональность только для изображений SVG.
  • Здесь важная часть. Для каждого вложения мы создаем новую функцию и передаем element в качестве ссылки. Внутри этого мы создаем вызов AJAX . Именно здесь мы извлекаем data-id и вызываем нашу PHP-функцию, которую мы зарегистрировали ранее. Наше действие называется svg_get_attachment_url и это относится к функции, подключенной к действию wp_AJAX_svg_get_attachment_url .
  • Наша функция AJAX передает идентификатор вложения обратно в PHP, который мы используем для получения URL-адреса объекта. Мы передаем его обратно нашему вызову AJAX, чтобы затем его можно было добавить к element , визуально обновляя его.

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

WordPress SVG библиотека после

Дополнительные замечания:

  • Хорошая вещь в этом заключается в том, что он срабатывает всякий раз, когда изменяется DOM, например, при начальной загрузке библиотеки, прокрутке библиотеки (загрузке новых вложений), а также при добавлении нового вложения в библиотеку и его загрузке.

  • Скорость, с которой вы видите ваши SVG-изображения, будет полностью зависеть от WordPress, так как каждое вложение SVG должно выполнить свой собственный вызов AJAX, а затем передать обратно свой URL, заставляя браузер загрузить новое изображение. Мы фактически ждем дважды, что замедлит ход событий. Хотя все это работает, может потребоваться несколько секунд, чтобы все «встало» на свои места.

  • Еще одна интересная «особенность» ( проблема ) заключается в том, что при добавлении новых изображений в библиотеку мультимедиа все вложения обновляются, а это означает, что выборка AJAX и рендеринг изображений должны произойти снова. Здесь не так много всего, что можно отрегулировать, так как это часть динамического процесса медиа библиотеки.

Макет колонки медиа библиотеки

Когда вы просматриваете библиотеку мультимедиа с использованием традиционной компоновки столбцов, вы заметите, что SVG снова отображаются неправильно.

колонка медиа библиотеки перед

Причина, по которой это выглядит так, заключается в том, что у них нет заданной высоты или какого-либо CSS-стиля для их оформления. Нам нужно настроить их так же, как мы делали для раздела рекомендуемых изображений:

 /*adjust SVG images when displayed inside media library column view*/ table.media .column-title .media-icon img[src*='.svg']{ width: 100%; height: auto; } 

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

колонка медиа библиотеки после

Media Attachment Preview

Когда вы находитесь внутри макета «Сетка» для библиотеки мультимедиа, вы можете щелкнуть элемент, чтобы открыть его в модальном окне, в котором отображаются метаданные вложений, это еще одна область, которую нам нужно настроить, чтобы отображались наши SVG.

Вот как это выглядит по умолчанию, обратите внимание на значок по умолчанию.

подробности вложения svg перед

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

Давайте вернемся к нашему файлу JavaScipt и добавим следующее:

 //Observer to adjust the media attachment modal window var attachmentPreviewObserver = new MutationObserver(function(mutations){ // look through all mutations that just occured for (var i=0; i < mutations.length; i++){ // look through all added nodes of this mutation for (var j=0; j < mutations[i].addedNodes.length; j++){ //get element var element = $(mutations[i].addedNodes[j]); //check if this is the attachment details section or if it contains the section //need this conditional as we need to trigger on initial modal open (creation) + next and previous navigation through media items var onAttachmentPage = false; if( (element.hasClass('attachment-details')) || element.find('.attachment-details').length != 0){ onAttachmentPage = true; } if(onAttachmentPage == true){ //find the URL value and update the details image var urlLabel = element.find('label[data-setting="url"]'); if(urlLabel.length != 0){ var value = urlLabel.find('input').val(); element.find('.details-image').attr('src', value); } } } } }); attachmentPreviewObserver.observe(document.body, { childList: true, subtree: true }); 

Вот как это все работает:

  • Мы создаем новый ‘Mutation Observer’ и прикрепляем его к телу, ища все изменения (включая дочерние узлы и всех их детей).
  • Мы перебираем все мутации и добавляем узлы. Мы ищем элемент, который имеет либо класс attachment-details или один из его потомков. Причина, по которой у нас есть это условие, заключается в том, что оно срабатывает при первом открытии модального окна и при каждом обновлении модального режима (путем нажатия кнопок «Далее» и «Предыдущий»). Это связано с тем, что при перемещении по самому триггерному элементу будет DOM-элемент attachment-details .
  • Как только мы узнаем, что находимся в нужном месте, нам нужно найти элемент URL и извлечь его. Как только мы его получим, мы заполняем наш предварительный просмотр изображением SVG.

После того, как мы все закончим, модальность деталей вложения теперь выглядит так:

подробности вложения svg после

Вывод на фронтэнд

Когда WordPress выводит изображения с SVG-контентом в качестве источника, часто вы обнаружите, что ничего не будет видно. Это вызвано тем, что в SVG не заданы правильная ширина и высота в качестве атрибутов или CSS (что имеет смысл, учитывая, что SVG не поддерживаются).

Чтобы заставить это работать, нам нужно добавить еще один стиль, который будет применяться и сделать наши SVG-элементы отзывчивыми.

 /*sets all SVG's to be responsive. displaying at full width*/ img[src*='.svg']{ width: 100%; height: auto; } 

После того, как вы добавите это в свой style.css все ваши SVG-изображения будут растянуты на полную ширину и сохранят свои пропорции (в современных браузерах).

Вот пример того, как стандартное изображение SVG теперь выглядит с его новым стилем.

SVG выходной интерфейс

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

Завершение всего этого

С этими изменениями вы сможете использовать SVG и взаимодействовать с ними, как и любое другое изображение, имея возможность быстро просматривать их и манипулировать ими, не беспокоясь о том, какой SVG какой.

Надеемся, что в какой-то момент SVG будут введены в ядро ​​WordPress, и все это будет беспрепятственно обрабатываться в бэк-энде для вас, но до тех пор эти обходные пути придется делать.

Дополнительную информацию можно найти в статье Алекса Уокерса «Руководство дизайнера по работе с SVG — Pt 1» и статья Марии Антониетты Перны « Холст против SVG: выбор правильного инструмента для работы» .