Способы обработки рендеринга SVG в WordPress?

9

С развитием интернет-браузеров я чувствую себя все более и более комфортно, используя SVGS при кодировании сайтов ... особенно для иконок и простой графики, которую можно заменить на лету pngs.

Похоже, WordPress почти поддерживает SVGS. Я говорю почти потому что:

  1. По умолчанию это не разрешенный тип файла в WordPress. Так что вам нужно добавить это перед загрузкой SVG

  2. Вы не можете увидеть миниатюру SVG в галерее Media. (см. изображение ниже)

  3. Иногда, когда вы добавляете его в редактор (через кнопку добавления мультимедиа), редактор не знает размер svg, поэтому, хотя он добавляет svg как изображение, он имеет ширину и высоту ноль.

  4. Когда вы нажимаете «изменить изображение» во всплывающем окне загрузки мультимедиа, вы получаете сообщение «изображение не существует». Смотрите изображение ниже.

Я в порядке с пунктом 1 в этом списке, но кто-нибудь выяснить, как исправить пункт 2 3 и 4?

введите описание изображения здесь введите описание изображения здесь

Обновление о пункте 1:

Чтобы разрешить новый тип MIME (например, SVG), вы можете просто добавить хук в functions.php

function allow_new_mime_type($mimes) {

    $mimes['svg'] = 'image/svg+xml';

    return $mimes;
}
add_filter( 'mime_types', 'allow_new_mime_type' );

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

Обновление о пункте 2:

Я немного покопался и отследил функцию, которая решает, является ли вложение изображением или нет. Кажется, что все сводится к этой функции в wp-includes / post.php

/**
 * Check if the attachment is an image.
 *
 * @since 2.1.0
 *
 * @param int $post_id Attachment ID
 * @return bool
 */
function wp_attachment_is_image( $post_id = 0 ) {
    $post_id = (int) $post_id;
    if ( !$post = get_post( $post_id ) )
        return false;

    if ( !$file = get_attached_file( $post->ID ) )
        return false;

    $ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false;

    $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );

    if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )
        return true;
    return false;
}

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

Я не уверен, почему последний оператор if возвращает ложь для SVG, хотя. Даже если я не добавлю расширение svg в массив $ image_exts, первое условие должно вернуть true, не так ли?

if ( 'image/' == substr($post->post_mime_type, 0, 6)

Это проверяет, соответствует ли 'image /' первым шести символам в типе mime, что для svg - это image / svg + xml (первые шесть - это 'image /').

ОБНОВИТЬ

При дальнейшем исследовании кажется, что проблема вовсе не в wp_attachment_is_image, а в том, что размер изображения (ширина и высота) не добавляется в метаданные вложения при загрузке SVG. Это потому, что функция для вычисления используемого изображения - это функция php getimagesize (), которая не возвращает размер изображения для SVG. Я нашел ответ на stackoverflow о функции getimagesize и о том, как ведут себя svgs. Смотрите это здесь.

gdaniel
источник
Установите плагин поддержки SVG, он отобразит svg в медиа-галерее - wordpress.org/plugins/svg-support
Nuno

Ответы:

10

Посмотрите wp_prepare_attachment_for_js(), что собирает метаданные вложений для использования на страницах мультимедиа. Одноименный фильтр позволяет нам добавлять или изменять метаданные.

Следующий пример можно добавить в functions.php. Примечание: для этого требуется поддержка SimpleXML в PHP.

function common_svg_media_thumbnails($response, $attachment, $meta){
    if($response['type'] === 'image' && $response['subtype'] === 'svg+xml' && class_exists('SimpleXMLElement'))
    {
        try {
            $path = get_attached_file($attachment->ID);
            if(@file_exists($path))
            {
                $svg = new SimpleXMLElement(@file_get_contents($path));
                $src = $response['url'];
                $width = (int) $svg['width'];
                $height = (int) $svg['height'];

                //media gallery
                $response['image'] = compact( 'src', 'width', 'height' );
                $response['thumb'] = compact( 'src', 'width', 'height' );

                //media single
                $response['sizes']['full'] = array(
                    'height'        => $height,
                    'width'         => $width,
                    'url'           => $src,
                    'orientation'   => $height > $width ? 'portrait' : 'landscape',
                );
            }
        }
        catch(Exception $e){}
    }

    return $response;
}
add_filter('wp_prepare_attachment_for_js', 'common_svg_media_thumbnails', 10, 3);
мистифицировать
источник
2

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

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

Все изображения до этого были растровыми. Система обработки изображений в WordPress была написана специально для того, чтобы справиться с ними, и этот неотъемлемый дизайн находится в каждой точке системы.

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

Мультимедийная система постепенно перестраивается с акцентом на «медленно». Необходимо поддерживать обратную совместимость и внедрять новые проекты. Кроме того, большинство людей гораздо больше заинтересованы в поддержке видео, аудио и плейлистов. По мере того как эта работа по редизайну завершена, а разделы библиотеки становятся все более абстрактными, со временем такие вещи станут легче поддерживать. Но это еще не там, и это не будет какое-то время. Вот почему SVG-тип MIME не поддерживается, потому что добавление этого MIME-типа до тех пор, пока не будут работать все основные части, будет дорогой к поломке.

Для SVG wp_attachment_is_imageдолжен возвращать false, потому что wp_attachment_is_imageиспользуется для определения, показывать или нет кнопку редактора и image_downsizeпытается ли изменить размер изображения в миниатюры и тому подобное. Ни один из которых не будет работать для SVG в любом случае. Чтобы должным образом поддерживать SVG, вам нужно написать новую систему для добавления метаданных для этих изображений полностью, а затем добавить поддержку для нее во всех местах, где могут использоваться метаданные. Как вы можете себе представить, это не маленькая работа.

эфирное масло
источник
1
SVGs имеют размер (область просмотра и окно просмотра), он просто более «виртуален», чем фиксированные пиксельно-зависимые размеры растровых изображений.
Rarst
1

Просто прочитав исходный код (не тестируя), я вижу, что расширение должно соответствовать:

if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )

который читается как (псевдокод)

if image/- это первые 6 символов в свойстве $ post для объекта post_mime_type ИЛИ есть расширение ИЛИ import- это свойство $ post для объекта post_mime_type И текущее расширение файла равно одному из (Array)

А это значит, что последнее утверждение всегда будет решать, ifокажется ли это правдой или нет.

Из того, что я могу прочитать get_attached_file(), есть фильтр, который позволит подделать расширение:

return apply_filters( 'get_attached_file', $file, $attachment_id );

Другими словами, вы можете попытаться вернуть тот же файл, но с другим расширением. Это не будет конфликтовать с другими частями, как wp_attachment_is_image()только возвращается bool.

кайзер
источник