web-dev-qa-db-ja.com

ワードプレスでSVGレンダリングを処理する方法は?

インターネットブラウザの進歩に伴い、私はウェブサイトをコーディングする際にSVGSを使用することがますます快適になってきました...特にアイコン、およびpngでその場で置き換えることができる単純なグラフィック。

WordpressがほぼSVGSをサポートしているようです。私はほとんど言う理由:

  1. デフォルトではワードプレスで許可されているファイルタイプではありません。だからSVGをアップロードする前にそれを追加する必要があります

  2. メディアギャラリーにSVGのサムネイルが表示されません。 (下の画像を参照)

  3. メディア追加ボタンを使ってエディタに追加すると、エディタがSVGサイズを認識しないことがあります。そのため、SVGがイメージとして追加されても、幅と高さは0になります。

  4. メディアアップロードポップアップ内から[画像を編集]をクリックすると、[画像が存在しません]というメッセージが表示されます。下の画像を見てください。

このリストの項目1に問題はありませんが、項目2、3、および4の修正方法を誰かが理解していますか。

enter image description hereenter image description here

アイテム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文がsvgsに対してfalseを返すのかわからない。 svg拡張子を配列$ image_extsに追加しなくても、最初の条件でtrueが返されるはずです。

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

これは、 'image /'がMIMEタイプの最初の6文字に等しいかどうかをチェックします。svgの場合、これはimage/svg + xmlです(最初の6文字は "image /"です)。

_ update _

さらに調査すると、問題はまったくwp_attachment_is_imageにあるのではなく、SVGがアップロードされたときに画像サイズ(幅と高さ)が添付ファイルのメタデータに追加されていないためです。これは、使用される画像を計算するための関数がphp関数getimagesize()であり、SVGの画像サイズを返さないためです。 getimagesize関数とsvgsの動作についてstackoverflowで答えを見つけました。 ここで見てください。

9
gdaniel

wp_prepare_attachment_for_js()を見てください。これは、メディアページで使用する添付ファイルのメタデータを収集するものです。同音異義語フィルタを使用すると、メタデータを追加または変更できます。

次の例はfunctions.phpに入れることができます。注:これにはPHPでのSimpleXMLサポートが必要です。

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);
9
Josh

これは、プラグインやいくつかの小さなコードセットで簡単に「ハッキング」できるものではありません。

一言で言えば、SVGは概して、それ以前のすべてのイメージという意味では「イメージ」ではありません。 SVGはベクトルベースの画像であり、ウェブ上で本物の牽引力を得た最初のものです。

それ以前のすべての画像はビットマップベースです。 WordPressの画像処理システムはそれらを処理するために特別に書かれたもので、この固有のデザインはシステムのあらゆるところに配置されています。

たとえば、画像に幅と高さがあることは基本的な前提です。 SVGはどちらも持っていない、彼らは任意のサイズにすることができます。 WordPressに組み込まれている画像のための全体的な基本的な「エディタ」がありますが、その機能は実際にはSVGには適用できません。

マルチメディアシステムはゆっくりと再開発されており、ここでは「ゆっくり」を強調しています。維持されるべき多くの後方互換性と実行されるべき新しい設計があります。さらに、ほとんどの人はビデオ、オーディオ、およびプレイリストのサポートにはるかに興味を持っています。この再設計作業が完了し、ライブラリのセクションがより抽象化されるにつれて、この種のことは時間の経過とともにサポートしやすくなります。しかし、それはまだありません、そしてそれはしばらくの間はないでしょう。これが、SVGのMIMEタイプがサポートされていない理由です。基礎となる部分がすべて機能するまでそのMIMEタイプを追加すると、破損する可能性があるからです。

SVGの場合、wp_attachment_is_imageはエディタボタンを表示するかどうか、およびwp_attachment_is_imageが画像をサムネイルなどにリサイズしようとするかどうかを決定するために使用されるため、image_downsizeはfalseを返す必要があります。どちらもSVGにはうまくいきません。 SVGを適切にサポートするには、それらの画像のメタデータを完全に追加するための新しいシステムを作成してから、メタデータが使用される可能性のあるすべての場所でそれをサポートする必要があります。ご想像のとおり、それは小さな仕事ではありません。

2
Otto

(テストではなく)ソースを読むだけで、拡張機能が一致する必要があることがわかります。

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

(擬似コード)

image/が$ postオブジェクトのpost_mime_typeプロパティORの最初の6文字である場合、拡張子がありますOR importは$ postオブジェクトのpost_mime_typeプロパティで、現在のファイル拡張子は(Array)のいずれかです。

そしてそれは、最後のステートメントがifが真かどうかを常に決定することを意味します。

get_attached_file() で読むことができるものから、 偽造 拡張子を許可するフィルタがあります。

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

言い換えれば、あなたは同じファイルを返すことを試みることができますが、異なる拡張子を持っています。 wp_attachment_is_image()は単にboolを返すので、他の部分と衝突しません。

1
kaiser