Maneiras de manipular a renderização SVG no wordpress?

9

Com o avanço dos navegadores de internet, eu me encontro cada vez mais à vontade usando 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. Não é por padrã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 (via botão adicionar mídia), o editor não sabe o tamanho do svg, portanto, embora adicione o svg como uma imagem, ele tem largura e altura de zero.

  4. Quando você clica em "editar imagem" de dentro do pop-up de upload da mídia, 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?

Atualize sobre o item 1:

Para permitir um novo tipo de mime (como SVG), basta 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 em este tutorial . Isso só resolve o item 1, que, como mencionei antes, não é um problema para mim (embora eu ache que deveria ser permitido por padrão).

Atualize sobre o item 2:

Eu fiz algumas pesquisas e localizei a função que decide se um anexo é uma imagem ou não. Parece que tudo se resume a essa função em 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 série de extensões de imagem válidas definidas nesta função. Não vejo nenhum filtro que possa ser usado para modificar esse array. Mas isso é um começo ...

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

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

Isso verifica se 'image /' é enqual para o primeiro seis caractere no tipo mime, que para svg é image / svg + xml (o primeiro seis é "image /").

UPDATE

Após investigação adicional, parece que o problema não é 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 porque a função para calcular a imagem usada é a função php getimagesize (), que não retorna um tamanho de imagem para o SVG. Eu encontrei uma resposta no stackoverflow sobre a função getimagesize e sobre como os svgs se comportam. Veja aqui.

    
por gdaniel 12.08.2014 / 00:20

3 respostas

9

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

O exemplo a seguir pode ser colocado em functions.php. Nota: isso requer suporte a SimpleXML no 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);
    
por Josh 09.04.2016 / 19:50
2

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

O mais curto é que os SVGs, em geral, não são "imagens" no sentido de todas as imagens que vieram antes. Os SVGs são imagens baseadas em vetores e os primeiros a obter uma tração real na web.

Todas as imagens anteriores foram baseadas em bitmap. O sistema de manipulação de imagens 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 de que as imagens têm larguras e alturas, por exemplo. SVGs não têm nenhum, eles podem ser de qualquer tamanho. Há todo um "editor" básico para imagens embutidas no WordPress, nenhuma das funcionalidades pode ser aplicada aos SVGs.

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

Para SVGs, o wp_attachment_is_image deve retornar falso, porque wp_attachment_is_image é usado para determinar se deve ou não mostrar o botão do editor e se image_downsize tenta ou não redimensionar a imagem nas miniaturas e tal. Nenhum dos dois funcionaria para SVGs. Para suportar adequadamente os SVGs, você precisaria escrever um novo sistema para adicionar metadados para essas imagens inteiramente e depois adicionar suporte a ele em todos os lugares em que os metadados pudessem ser usados. Como você pode imaginar, isso não é um trabalho pequeno.

    
por Otto 19.10.2014 / 20:46
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 primeiros 6 caracteres na propriedade post_mime_type do objeto post $     OU há uma extensão     OU import é a propriedade post_mime_type $ post objects     E a extensão de arquivo atual é um dos (Array)

E isso significa que a última declaração sempre decidirá se o if é verdadeiro ou não.

Pelo que eu posso ler em get_attached_file() , há um filtro que permitiria fingir 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 o wp_attachment_is_image() apenas retorna bool .

    
por kaiser 19.10.2014 / 18:12

Tags