問題描述
到目前為止,我的主題中沒有 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-image – url 。
這是修復
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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。