問題描述

到目前為止,我的主題中沒有 background-image 縮圖的問題。然而,現在我正在嘗試使用 SVG 作為特色影像,有些東西正在破裂。問題似乎與由 wp_get_attachment_image_src()返回為零的 SVG 的寬度有關。所以我想做的是弄清楚如何從 SVG 中提取寬度和高度資訊,然後將它們設定為 SVG 資料庫欄位中的適當值,這並不容易。

注意:上傳或呈現 svgs 並不存在一般問題,它們在我的徽標中顯示正常。

錯誤和程式碼:zero-width 的證據

這是 Wordpress 在頁面上丟擲的錯誤:Warning: Division by zero in /wp-content/themes/tesseract/functions.php on line 771

這是在錯誤之前的 functions.php 中的程式碼 (在第 771 行) 。

    /*759*/ function tesseract_output_featimg_blog() {
    /*760*/
    /*761*/ global $post;
    /*762*/
    /*763*/ $thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
    /*764*/ $featImg_display = get_theme_mod('tesseract_blog_display_featimg');
    /*765*/ $featImg_pos = get_theme_mod('tesseract_blog_featimg_pos');
    /*766*/
    /*767*/ $w = $thumbnail[1]; /* supposed to return thumbnail width */
    /*768*/ $h = $thumbnail[2];  /* supposed to return thumbnail height */
    /*769*/ $bw = 720;
    /*770*/ $wr = $w/$bw;
    /*771*/ $hr = $h/$wr; /**** this is the line that throws the error ****/

您可以看到有一個與 $wr 作為分母的部門。 $wr 似乎被計算為零,因為它的唯一 non-constant 因子 $w 也是零 (另一個因素是 720,所以不能怪) 。 $w 的值由 $thumbnail[1]確定。 $thumbnail[1]的值是在第 763 行設定的,程式碼如下:

$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );

並且根據 the Codex,函式 wp_get_attachment_image_src(即 $thumbnail[1]) 的返回陣列中的第二個值確實是縮圖的寬度。該值似乎為零,因為它與 $w 的值相同,它確實是 771 行的分母。:(

重要說明:我的主題實現縮圖為 background-images

我使用的父主題”Tesseract” 將特徵影像作為錨點/<a> 元素的背景影像,而不是將它們放置為<img> 元素。我不相信這是問題的原因,但提供解決方案時,應該與 background-images 相容,而不是<img> 物件。

無法修改#1:

我找到了 this webpage,它為使用 SVG 作為特徵影像的問題提供了一個修復。這表明這個問題與寬度的計算有關。但是,我不能應用此修復程式,因為它是一個 img 元素,具有 SVG 作為 src,我有一個<a> 元素,其 SVG 位置設定為 background-imageurl

這是修復

function custom_admin_head() {
  $css = '';
  $css = 'td.media-icon img[src$=".svg"] { width: 100% !important; height: auto !important; }';
  echo '<style type="text/css">'.$css.'</style>';
}
add_action('admin_head', 'custom_admin_head');

修復#2(min-width 透過 CSS) 沒有工作

根據我從上述頁面得到的想法,可能是寬度可能是問題,我嘗試使用 CSS 將<a> 設定為 50%的 min-width 。這是程式碼:

a.entry-post-thumbnail.above {
    min-width: 50% !important;
}

我的開發人員工具顯示,CSS “took”,min-width 的設定為 50%。 Still WP 丟擲的影像沒有顯示相同的錯誤。也許 CSS 沒有在 functions.php 之前設定它執行 wp_get_attachment_image_src,所以沒關係?

任何人都有關於如何解決這個零計算的任何線索?我真的想讓這個工作與 background-images,而不必覆蓋太多的父主題。

修復#3(掛起一個過濾器) 沒有工作。

在 @Milo,@NathanJohnson 和 @prosti 的幫助下,我可以嘗試過濾器來更改 wp_get_attachment_image_src()。程式碼不會產生錯誤,但它不會消除分裂錯誤或使 SVG 顯示。這是我放在 functions.php 中的程式碼段。優先事項也許是錯誤的? :

add_filter( 'wp_get_attachment_image_src', 'fix_wp_get_attachment_image_svg', 10, 4 );  /* the hook */

     function fix_wp_get_attachment_image_svg($image, $attachment_id, $size, $icon) {
        if (is_array($image) && preg_match('/.svg$/i', $image[0]) && $image[1] == 1) {
            if(is_array($size)) {
                $image[1] = $size[0];
                $image[2] = $size[1];
            } elseif(($xml = simplexml_load_file($image[0])) !== false) {
                $attr = $xml->attributes();
                $viewbox = explode(' ', $attr->viewBox);
                $image[1] = isset($attr->width) && preg_match('/d+/', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
                $image[2] = isset($attr->height) && preg_match('/d+/', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
            } else {
                $image[1] = $image[2] = null;
            }
        }
        return $image;
    }

底線:

我相信我需要弄清楚如何從 SVG 檔案本身提取寬度資訊,並將其新增到 WP 資料庫中,然後在.7p 行執行計算。如果您知道如何,您的指導將非常受讚賞。

一些潛在有用的資源

  • This question 似乎有幫助的資訊,而 @Josh 提供的片段讓我終於可以在媒體庫中檢視我的 SVG,但是特色圖片仍然被打破。

  • This question 似乎有一些 XML-based 解決方案,但我不知道如何適應 WP 。

  • 下面的一位評論員也指出我對 This filter 的看法是相關的。

SVG 檔案的標題

這是 SVG 標題:

<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="475.419px" height="406.005px" viewBox="0 0 475.419 406.005" enable-background="new 0 0 475.419 406.005" xml:space="preserve">

最佳解決方案

我解決了!由於觸發維度提取和附件的 if 語句的第三個條件,修補程式#3(上) 中的過濾器不起作用:

if (is_array($image) && preg_match('/.svg$/i', $image[0]) && $image[1] == 1)

在第三個條件下,$image[1]是 WP 進入過濾器之前報告的 SVG 檔案的寬度。因為我知道它的值,寬度是 0(從上面的 「zero-division 錯誤」) 我懷疑這個值需要改變以匹配它。我將 if 的最終 1 更改為 0 和… 。分裂錯誤消失,影像顯示,美麗,所以我可以廣告!

我能夠發現這一點,因為在許多論壇上,人們抱怨說,SVG 不正確地獲得 1px 的分配寬度。這在 WP 的某些版本中可能是這種情況,但在我的 WP 4.7.2 媒體庫中,沒有 SVG 的維度,甚至沒有張貼 1px 的維度。相反,在我的情況下,根本就沒有關於維度的後設資料。

我認為過濾器的靈活版本將允許應用寬度為 1 或 0,對於具有 1px 問題的人和像我這樣的人,寬度為 0. 下面我包括修復,使用 $image[1] <= 1 作為 if 語句的第三個條件而不是 $image[1] == 1,但我想你也可以使用它:( ($image[1] == 0) || ($image[1] == 1) )

工作過濾器

 add_filter( 'wp_get_attachment_image_src', 'fix_wp_get_attachment_image_svg', 10, 4 );  /* the hook */

 function fix_wp_get_attachment_image_svg($image, $attachment_id, $size, $icon) {
    if (is_array($image) && preg_match('/.svg$/i', $image[0]) && $image[1] <= 1) {
        if(is_array($size)) {
            $image[1] = $size[0];
            $image[2] = $size[1];
        } elseif(($xml = simplexml_load_file($image[0])) !== false) {
            $attr = $xml->attributes();
            $viewbox = explode(' ', $attr->viewBox);
            $image[1] = isset($attr->width) && preg_match('/d+/', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
            $image[2] = isset($attr->height) && preg_match('/d+/', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
        } else {
            $image[1] = $image[2] = null;
        }
    }
    return $image;
}

感謝大家的幫助,這真的是一個團隊的努力!

次佳解決方案

很難猜出像我這樣的 WordPress 愛好者可能是什麼問題,但是因為你在迴圈中 ping 了我…

只是提到你還沒有共享主題檔案…

File: wp-includes/media.php
804: /**
805:  * Retrieve an image to represent an attachment.
806:  *
807:  * A mime icon for files, thumbnail or intermediate size for images.
808:  *
809:  * The returned array contains four values: the URL of the attachment image src,
810:  * the width of the image file, the height of the image file, and a boolean
811:  * representing whether the returned array describes an intermediate (generated)
812:  * image size or the original, full-sized upload.
813:  *
814:  * @since 2.5.0
815:  *
816:  * @param int          $attachment_id Image attachment ID.
817:  * @param string|array $size          Optional. Image size. Accepts any valid image size, or an array of width
818:  *                                    and height values in pixels (in that order). Default 'thumbnail'.
819:  * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
820:  * @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
821:  */
822: function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) {
823:    // get a thumbnail or intermediate image if there is one
824:    $image = image_downsize( $attachment_id, $size );
825:    if ( ! $image ) {
826:        $src = false;
827:
828:        if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) {
829:            /** This filter is documented in wp-includes/post.php */
830:            $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
831:
832:            $src_file = $icon_dir . '/' . wp_basename( $src );
833:            @list( $width, $height ) = getimagesize( $src_file );
834:        }
835:
836:        if ( $src && $width && $height ) {
837:            $image = array( $src, $width, $height );
838:        }
839:    }

這部分與:

@list( $width, $height ) = getimagesize( $src_file );

看起來像 SVG 影像 don’t have the size info 的問題。他們只是適合容器。

所以你可以建立自己的版本的 wp_get_attachment_image_src,你可以在某種程度上設定大小。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。