Cara menangani rendering SVG di wordpress?

9

Dengan kemajuan browser internet, saya menemukan diri saya semakin nyaman menggunakan SVGS ketika meng-coding situs web ... terutama untuk ikon, dan grafik sederhana yang dapat diganti dengan cepat menggunakan pngs.

Sepertinya wordpress hampir mendukung SVGS. Saya katakan hampir karena:

  1. Ini bukan jenis file yang diizinkan secara default di wordpress. Jadi, Anda perlu menambahkan itu sebelum mengunggah SVG

  2. Anda tidak dapat melihat thumbnail SVG di galeri Media. (lihat gambar di bawah)

  3. Terkadang ketika Anda menambahkannya ke editor (melalui tombol add media) editor tidak tahu ukuran svg, jadi meskipun ia menambahkan svg sebagai gambar, ia memiliki lebar dan tinggi nol.

  4. Ketika Anda mengklik "edit gambar" dari dalam popup unggahan media, Anda mendapat pesan yang mengatakan "gambar tidak ada". Lihat gambar di bawah.

Saya setuju dengan item 1 dalam daftar ini, tetapi adakah yang tahu bagaimana cara memperbaiki item 2 3, dan 4?

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Perbarui tentang item 1:

Untuk mengizinkan tipe mime baru (seperti SVG), Anda bisa menambahkan hook di functions.php

function allow_new_mime_type($mimes) {

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

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

Sekarang Anda harus dapat mengunggah SVG. Anda dapat menemukan informasi lebih lanjut dalam tutorial ini . Ini hanya memecahkan item 1, yang seperti yang saya sebutkan sebelumnya, itu bukan masalah bagi saya (meskipun saya pikir itu harus diizinkan secara default).

Perbarui tentang item 2:

Saya melakukan penggalian dan melacak fungsi yang memutuskan apakah lampiran adalah gambar atau tidak. Tampaknya semuanya berujung pada fungsi ini di wp-include / 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;
}

Seperti yang Anda lihat ada array ekstensi gambar yang valid didefinisikan dalam fungsi ini. Saya tidak melihat filter apa pun yang dapat digunakan untuk mengubah array itu. Tapi itu awal ...

Saya tidak yakin mengapa pernyataan if terakhir mengembalikan false untuk svgs. Bahkan jika saya tidak menambahkan ekstensi svg ke array $ image_exts, kondisi pertama harus mengembalikan true, bukan?

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

Itu memeriksa apakah 'gambar /' sama dengan enam karakter pertama dalam tipe mime, yang untuk svg adalah gambar / svg + xml (enam pertama adalah "gambar /").

MEMPERBARUI

Setelah diselidiki lebih lanjut, tampaknya masalahnya bukan pada wp_attachment_is_image sama sekali, tetapi karena ukuran gambar (lebar dan tinggi) tidak ditambahkan ke metadata lampiran ketika SVG diunggah. Itu karena fungsi untuk menghitung gambar yang digunakan adalah fungsi php getimagesize (), yang tidak mengembalikan ukuran gambar untuk SVG. Saya menemukan jawaban pada stackoverflow tentang fungsi getimagesize dan tentang bagaimana svgs berperilaku. Lihat di sini.

gdaniel
sumber
Instal plugin dukungan SVG yang menampilkan svg di galeri media - wordpress.org/plugins/svg-support
Nuno Sarmento

Jawaban:

10

Lihatlah wp_prepare_attachment_for_js(), yang mengumpulkan metadata lampiran untuk digunakan pada halaman Media. Filter eponymous memungkinkan kita menambah atau mengubah metadata.

Contoh berikut dapat dimasukkan ke functions.php. Catatan: ini membutuhkan dukungan SimpleXML di 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);
Josh
sumber
2

Ini bukan sesuatu yang Anda dapat dengan mudah "meretas" dengan plugin atau beberapa set kode.

Singkatnya adalah bahwa SVG, pada umumnya, bukan "gambar" dalam arti semua gambar yang datang sebelumnya. SVG adalah gambar berbasis vektor, dan yang pertama mendapatkan traksi nyata di web.

Semua gambar sebelum itu berbasis bitmap. Sistem penanganan gambar WordPress ditulis secara khusus untuk mengatasinya, dan desain yang melekat ini terletak di setiap titik dalam sistem.

Ini adalah asumsi mendasar bahwa gambar memiliki lebar dan tinggi, misalnya. SVG tidak memiliki keduanya, ukurannya bisa berapa saja. Ada "editor" dasar untuk gambar yang dibangun di WordPress, tidak ada fungsi yang benar-benar dapat diterapkan pada SVG.

Sistem multimedia perlahan-lahan sedang dikembangkan kembali, dengan penekanan di sini pada "perlahan". Ada banyak kompatibilitas ke belakang untuk dipertahankan dan desain baru untuk diimplementasikan. Selain itu, kebanyakan orang jauh lebih tertarik untuk mendukung video, audio, dan daftar putar. Ketika pekerjaan mendesain ulang ini selesai, dan bagian-bagian perpustakaan menjadi lebih abstrak, maka hal semacam ini akan menjadi lebih mudah untuk didukung seiring waktu. Tapi itu belum ada di sana, dan tidak akan lama. Inilah sebabnya mengapa tipe mime SVG tidak didukung, karena menambahkan tipe mime sampai semua bagian yang mendasarinya berfungsi menjadi jalan menuju kerusakan.

Untuk SVG, itu wp_attachment_is_imageharus mengembalikan false, karena wp_attachment_is_imagedigunakan untuk menentukan apakah akan menampilkan tombol editor atau tidak dan image_downsizemencoba mengubah ukuran gambar menjadi thumbnail dan semacamnya. Tidak ada yang akan bekerja untuk SVG. Untuk mendukung SVG dengan benar, Anda harus menulis sistem baru untuk menambahkan metadata sepenuhnya untuk gambar-gambar itu, dan kemudian menambahkan dukungan untuk itu di semua tempat yang mungkin digunakan metadata. Seperti yang dapat Anda bayangkan, itu bukan pekerjaan kecil.

Otto
sumber
1
SVG memang memiliki ukuran (viewport dan kotak tampilan), itu hanya lebih "virtual" daripada dimensi bitmap yang bergantung pada piksel.
Jarang
1

Hanya dengan membaca sumbernya (bukan pengujian), saya dapat melihat bahwa ekstensi harus cocok:

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

yang berbunyi (kode semu)

jika image/6 karakter pertama dalam properti $ post objek post_mime_type ATAU ada ekstensi ATAU importadalah properti $ post object post_mime_type DAN ekstensi file saat ini adalah salah satu dari (Array)

Dan itu berarti bahwa pernyataan terakhir akan selalu memutuskan apakah ifternyata benar atau tidak.

Dari apa yang dapat saya baca get_attached_file(), ada filter yang memungkinkan memalsukan ekstensi:

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

Dengan kata lain, Anda dapat mencoba mengembalikan file yang sama tetapi dengan ekstensi yang berbeda. Itu tidak akan bertentangan dengan bagian lain, karena wp_attachment_is_image()hanya kembali bool.

kaisar
sumber