วิธีจัดการกับการเรนเดอร์ SVG ใน wordpress?


9

ด้วยความก้าวหน้าของอินเทอร์เน็ตเบราว์เซอร์ฉันพบว่าตัวเองสบายใจมากขึ้นเมื่อใช้ SVGS ในการเข้ารหัสเว็บไซต์ ... โดยเฉพาะอย่างยิ่งสำหรับไอคอนและกราฟิกง่าย ๆ ที่สามารถเปลี่ยนได้ทันทีโดย pngs

ดูเหมือนว่า WordPress เกือบรองรับ SVGS ฉันพูดเกือบเพราะ:

  1. ไม่ใช่ค่าเริ่มต้นประเภทไฟล์ที่อนุญาตใน wordpress ดังนั้นคุณต้องเพิ่มมันก่อนที่จะอัพโหลด SVG

  2. คุณไม่เห็นภาพขนาดย่อของ SVG ในแกลเลอรี่สื่อ (ดูภาพด้านล่าง)

  3. บางครั้งเมื่อคุณเพิ่มลงในตัวแก้ไข (ผ่านปุ่มเพิ่มสื่อ) ตัวแก้ไขไม่ทราบขนาด svg ดังนั้นแม้ว่าจะเพิ่ม svg เป็นรูปภาพ แต่ก็มีความกว้างและความสูงเป็นศูนย์

  4. เมื่อคุณคลิกที่ "แก้ไขภาพ" จากภายในป๊อปอัปอัปโหลดสื่อคุณจะได้รับข้อความว่า "ไม่มีภาพ" ดูภาพด้านล่าง

ฉันใช้ได้กับรายการที่ 1 ในรายการนี้ แต่มีใครบ้างที่คิดว่ารายการแก้ไข 2 3 และ 4 เป็นอย่างไร

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

อัปเดตเกี่ยวกับรายการ 1:

ในการอนุญาตประเภท mime ใหม่ (เช่น SVG) คุณสามารถเพิ่ม hook ใน 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-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;
}

ในขณะที่คุณสามารถเห็นว่ามีส่วนขยายภาพที่ถูกต้องที่กำหนดไว้ในฟังก์ชั่นนี้ ฉันไม่เห็นตัวกรองใด ๆ ที่สามารถใช้ในการปรับเปลี่ยนอาร์เรย์นั้น แต่นั่นเป็นการเริ่มต้น ...

ฉันไม่แน่ใจว่าทำไมคำสั่งสุดท้ายถ้าส่งกลับค่าเท็จสำหรับ svgs แม้ว่าฉันจะไม่เพิ่มส่วนขยาย svg ไปยังอาร์เรย์ $ image_exts แต่เงื่อนไขแรกควรกลับมาจริงใช่ไหม

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

ที่ตรวจสอบว่า 'image /' มีผลกับอักขระหกตัวแรกในประเภท mime ซึ่งสำหรับ svg คือ image / svg + xml (หกตัวแรกคือ "image /")

UPDATE

เมื่อทำการตรวจสอบเพิ่มเติมดูเหมือนว่าปัญหาไม่ได้อยู่ที่ wp_attachment_is_image เลย แต่เนื่องจากขนาดของภาพ (ความกว้างและความสูง) ไม่ได้ถูกเพิ่มลงในข้อมูลเมตาของสิ่งที่แนบเมื่ออัพโหลด SVG นั่นเป็นเพราะฟังก์ชั่นในการคำนวณภาพที่ใช้คือฟังก์ชั่น php getimagesize () ซึ่งไม่ส่งคืนขนาดภาพสำหรับ SVG ฉันพบคำตอบใน stackoverflow เกี่ยวกับฟังก์ชั่น getimagesize และการทำงานของ svgs ดูที่นี่


ติดตั้งปลั๊กอินสนับสนุน SVG มันจะแสดง svg บนแกลเลอรี่สื่อ - wordpress.org/plugins/svg-support
Nuno Sarmento

คำตอบ:


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

นี่ไม่ใช่สิ่งที่คุณจะสามารถ "แฮ็ค" ด้วยปลั๊กอินหรือชุดโค้ดขนาดเล็ก

สั้น ๆ ก็คือ SVGs โดยและขนาดใหญ่ไม่ใช่ "ภาพ" ในแง่ของภาพทั้งหมดที่มีมาก่อนหน้านี้ SVGs เป็นภาพที่ใช้เวกเตอร์และเป็นภาพแรกที่ได้รับการลากบนเว็บ

ภาพทั้งหมดก่อนหน้านั้นเป็นบิตแมป ระบบจัดการรูปภาพของ WordPress นั้นเขียนขึ้นโดยเฉพาะเพื่อจัดการกับสิ่งเหล่านี้และการออกแบบโดยธรรมชาตินี้ตั้งอยู่ทุกจุดในระบบ

เป็นข้อสมมุติพื้นฐานว่าภาพมีความกว้างและความสูง SVG ไม่มีทั้งขนาดและขนาดใดก็ได้ มี "เครื่องมือแก้ไข" พื้นฐานทั้งหมดสำหรับรูปภาพที่สร้างขึ้นใน WordPress ไม่มีฟังก์ชันใดที่สามารถนำไปใช้กับ SVG ได้

ระบบมัลติมีเดียกำลังพัฒนาอย่างช้าๆโดยเน้นที่ "ช้า" ที่นี่ มีความเข้ากันได้แบบย้อนหลังมากมายที่ต้องดูแลรักษาและการออกแบบใหม่ที่จะนำมาใช้ นอกจากนี้คนส่วนใหญ่ให้ความสนใจในการสนับสนุนวิดีโอเสียงและเพลย์ลิสต์มากขึ้น เมื่องานออกแบบนี้เสร็จสิ้นและส่วนต่างๆของห้องสมุดกลายเป็นนามธรรมมากขึ้นดังนั้นสิ่งต่าง ๆ ประเภทนี้จะง่ายขึ้นที่จะได้รับการสนับสนุนเมื่อเวลาผ่านไป แต่มันยังไม่อยู่ที่นั่นและมันจะไม่เกิดขึ้นอีกซักพัก นี่คือสาเหตุที่ไม่รองรับประเภท Mime ของ SVG เนื่องจากการเพิ่มประเภท mime นั้นจนกว่าชิ้นส่วนต้นแบบทั้งหมดจะเป็นถนนที่จะแตก

สำหรับ SVGs wp_attachment_is_imageควรส่งคืนค่าเท็จเนื่องจาก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) )

สิ่งที่อ่านว่าเป็น (รหัสหลอก)

ถ้า image/เป็น 6 ตัวอักษรแรกในคุณสมบัติ $ post object post_mime_type หรือมีส่วนขยายหรือimportเป็น $ post object คุณสมบัติ post_mime_type และนามสกุลไฟล์ปัจจุบันเป็นหนึ่งใน (Array)

และนั่นหมายความว่าคำสั่งสุดท้ายจะตัดสินเสมอว่าสิ่งที่เกิดifขึ้นจริงหรือไม่

จากสิ่งที่ฉันสามารถอ่านได้get_attached_file()มีตัวกรองที่อนุญาตให้แกล้งทำส่วนขยาย:

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

คุณสามารถลองส่งคืนไฟล์เดิม แต่ใช้นามสกุลอื่น มันจะไม่ขัดแย้งกับส่วนอื่น ๆ เป็นเพียงผลตอบแทนwp_attachment_is_image()bool

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.