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


9

インターネットブラウザーの進歩に伴い、Webサイトのコーディング時にSVGSを使用することがますます快適になりました。特に、アイコンや、オンザフライでpngに置き換えることができるシンプルなグラフィックについては特にそうです。

ワードプレスはほとんどSVGSをサポートしているようです。私はほとんど理由でこう言います:

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

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

  3. (メディアの追加ボタンを使用して)エディターに追加する場合、エディターはsvgサイズを認識しないことがあります。そのため、svgを画像として追加しますが、幅と高さがゼロです。

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

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

ここに画像の説明を入力してください ここに画像の説明を入力してください

アイテム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ステートメントがsvgに対してfalseを返す理由はわかりません。$ image_exts配列にsvg拡張機能を追加しない場合でも、最初の条件はtrueを返す必要がありますね。

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

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

更新

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


-それはメディアギャラリーにSVG表示するプラグインSVGのサポートをインストールしwordpress.org/plugins/svg-support
ヌーノSarmento

回答:


10

を見てください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);

2

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

簡単に言えば、SVGは一般的に、それより前に来たすべてのイメージという意味では「イメージ」ではないということです。SVGはベクターベースの画像であり、Web上で実際に牽引力を発揮する最初の画像です。

それ以前のすべての画像はビットマップベースです。WordPressの画像処理システムは、それらに対処するために特別に作成されたものであり、この固有の設計はシステムのすべてのポイントに配置されています。

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

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

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


1
SVGにはサイズ(ビューポートとビューボックス)があり、ピクセルに依存するビットマップの固定サイズよりも「仮想的」です。
Rarst、2014年

1

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

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

これは(擬似コード)として読み取ります

場合 image/$ポストオブジェクトpost_mime_typeプロパティの最初の6つの文字であるORが拡張子はOR import$ポストがpost_mime_typeプロパティをオブジェクトと現在のファイルの拡張子は、(配列)の一つであります

つまり、最後のステートメントは、結果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.