问题描述
到目前为止,我的主题中没有 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。