Maneiras de lidar com renderização SVG no wordpress?


9

Com o avanço dos navegadores da Internet, me sinto cada vez mais confortável usando o SVGS ao codificar sites ... especialmente para ícones e gráficos simples que podem ser substituídos rapidamente por pngs.

Parece que o wordpress quase suporta SVGS. Eu digo quase porque:

  1. Por padrão, não é um tipo de arquivo permitido no wordpress. Então você precisa adicionar isso antes de fazer upload de SVGs

  2. Você não pode ver uma miniatura SVG na galeria Mídia. (veja a imagem abaixo)

  3. Às vezes, quando você o adiciona ao editor (por meio do botão adicionar mídia), o editor não sabe o tamanho do svg, portanto, embora ele adicione o svg como imagem, possui largura e altura zero.

  4. Quando você clica em "editar imagem" a partir do pop-up de upload de mídia, você recebe uma mensagem dizendo "a imagem não existe". Veja a imagem abaixo.

Estou bem com o item 1 desta lista, mas alguém descobriu como um item de correção 2 3 e 4?

insira a descrição da imagem aqui insira a descrição da imagem aqui

Atualização sobre o item 1:

Para permitir um novo tipo MIME (como SVG), você pode simplesmente adicionar um gancho em functions.php

function allow_new_mime_type($mimes) {

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

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

Agora você deve poder fazer upload de SVGs. Você pode encontrar mais informações neste tutorial . Isso resolve o item 1, que, como mencionei anteriormente, não é um problema para mim (embora eu ache que deve ser permitido por padrão).

Atualização sobre o item 2:

Eu pesquisei e localizei a função que decide se um anexo é uma imagem ou não. Parece que tudo se resume a essa função no 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;
}

Como você pode ver, há uma variedade de extensões de imagem válidas definidas nesta função. Não vejo nenhum filtro que possa ser usado para modificar essa matriz. Mas isso é um começo ...

Não sei por que a última declaração if retorna false para svgs. Mesmo se eu não adicionar a extensão svg ao array $ image_exts, a primeira condição deve retornar verdadeira, não deveria?

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

Isso verifica se 'image /' está enquadrado nos seis primeiros caracteres do tipo mime, que para svg é image / svg + xml (os seis primeiros são "image /").

ATUALIZAR

Após uma investigação mais aprofundada, parece que o problema não está relacionado com wp_attachment_is_image, mas porque o tamanho da imagem (largura e altura) não está sendo adicionado aos metadados do anexo quando o SVG é carregado. Isso ocorre porque a função para calcular a imagem usada é a função php getimagesize (), que não retorna um tamanho de imagem para SVG. Encontrei uma resposta no stackoverflow sobre a função getimagesize e sobre como os svgs se comportam. Veja aqui.


Instalar o suporte SVG plug-in que exibe o SVG na galeria de mídia - wordpress.org/plugins/svg-support
Nuno Sarmento

Respostas:


10

Dê uma olhada wp_prepare_attachment_for_js(), que é o que reúne os metadados do anexo para uso nas páginas Mídia. O filtro de mesmo nome permite adicionar ou alterar os metadados.

O exemplo a seguir pode ser colocado em functions.php. Nota: isso requer suporte ao SimpleXML em 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

Isso não é algo que você poderá facilmente "invadir" com um plug-in ou algum pequeno conjunto de códigos.

O resumo é que os SVGs, em geral, não são "imagens" no sentido de todas as imagens que vieram antes dele. SVGs são imagens baseadas em vetor e as primeiras a obter uma tração real na web.

Todas as imagens anteriores foram baseadas em bitmap. O sistema de manipulação de imagem do WordPress foi escrito especificamente para lidar com eles, e esse design inerente está localizado em todos os pontos do sistema.

É uma suposição subjacente que as imagens tenham larguras e alturas, por exemplo. SVGs não têm, eles podem ser de qualquer tamanho. Existe todo um "editor" básico para imagens incorporadas ao WordPress, nenhuma das funcionalidades que realmente se aplica aos SVGs.

O sistema multimídia está sendo reconstruído lentamente, com ênfase aqui em "lentamente". Há muita compatibilidade com versões anteriores a serem mantidas e novos designs a serem implementados. Além disso, a maioria das pessoas está muito mais interessada em oferecer suporte a vídeo, áudio e playlists. À medida que esse trabalho de reformulação é concluído, e as seções da biblioteca se tornam mais abstratas, esse tipo de coisa se torna mais fácil de suportar ao longo do tempo. Mas ainda não está lá e não será por um tempo. É por isso que o tipo mime SVG não é suportado, porque adicionar esse tipo mime até que todas as peças subjacentes funcionem seria um caminho para quebrar.

Para SVGs, o valor wp_attachment_is_imagedeve retornar false, porque wp_attachment_is_imageé usado para determinar se o botão do editor deve ser exibido ou não e se é necessário ou não image_downsizeredimensionar a imagem nas miniaturas e assim por diante. Nenhum dos quais funcionaria para SVGs de qualquer maneira. Para oferecer suporte adequado a SVGs, você precisará escrever um novo sistema para adicionar metadados para essas imagens inteiramente e, em seguida, adicionar suporte para todos os locais em que os metadados possam ser usados. Como você pode imaginar, isso não é um trabalho pequeno.


11
Os SVGs têm tamanho (viewport e view box), são apenas mais "virtuais" do que as dimensões fixas de bitmaps dependentes de pixel.
Rarst

1

Apenas lendo a fonte (não testando), posso ver que a extensão precisa corresponder:

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

que lê como (pseudo código)

se image/são os 6 primeiros caracteres na propriedade post_mime_type de objeto $ post OU existe uma extensão OR importé a propriedade post_mime_type de $ post objects E a extensão de arquivo atual é uma das (Matriz)

E isso significa que a última afirmação sempre decidirá se a ifverdade é verdadeira ou não.

Pelo que posso ler get_attached_file(), há um filtro que permitiria falsificar a extensão:

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

Em outras palavras, você pode tentar retornar o mesmo arquivo, mas com uma extensão diferente. Não entraria em conflito com outras partes, pois os wp_attachment_is_image()justos retornam bool.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.