Jusqu'à présent, les vignettes d'arrière-plan de mon thème ne me posaient aucun problème. Cependant, maintenant que j'essaie d'utiliser un SVG en tant qu'image sélectionnée, quelque chose se brise. Le problème semble lié à la largeur des SVG renvoyés à zéro par wp_get_attachment_image_src()
. Donc, ce que je suis en train d'essayer de faire, c'est de trouver comment extraire les informations de largeur et de hauteur du SVG, puis de leur attribuer les valeurs appropriées dans les champs de la base de données SVG, cela ne s'avère pas facile.
_ {Remarque: il n'y a pas de problème général lors du téléchargement ou du rendu des svgs, ils s'affichent correctement dans mon logo.} _
C'est l'erreur que Wordpress renvoie sur la page: Warning: Division by zero in /wp-content/themes/tesseract/functions.php on line 771
C'est le code dans functions.php avant l'erreur (à la ligne 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 ****/
Vous pouvez voir qu'il existe une division avec $wr
comme dénominateur. Il semble que $wr
soit calculé à zéro car son seul facteur non constant, $w
, est également égal à zéro (l'autre facteur est 720, il ne peut donc pas être blâmé). La valeur de $w
est déterminée par $thumbnail[1]
. La valeur de $thumbnail[1]
est définie à la ligne 763 avec le code suivant:
$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
Et selon le the Codex , la deuxième valeur dans le tableau de retour de la fonction wp_get_attachment_image_src
(c'est-à-dire $thumbnail[1]
) est bien la largeur de la vignette. Cette valeur semble être zéro, car c'est la même valeur que $w
, qui est effectivement le dénominateur de la ligne 771. :(
Le thème parent que j'utilise, "Tesseract", place les images en vedette en tant qu'images d'arrière-plan des ancres/éléments <a>
, au lieu de les placer en tant qu'éléments <img>
. Je ne crois pas que ce soit la cause du problème, mais lorsque des solutions sont proposées, elles doivent être compatibles avec les images d'arrière-plan et non les objets <img>
.
J'ai trouvé cette page Web qui résout les problèmes d'utilisation de SVG en tant qu'images. Cela suggère que le problème est lié au calcul de la largeur. Cependant, je ne peux pas appliquer ce correctif car il s'agit d'un élément img
qui a un SVG comme src
name__, j'ai un élément <a>
dont l'emplacement SVG est défini sur le background-image
-url
name__.
C'est le correctif
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');
Sur la base de l’idée que j’ai eu de la page ci-dessus, que la largeur de la pourrait être le problème, j’ai essayé de définir une largeur minimale de 50% en utilisant uniquement CSS pour le <a>
. Voici le code:
a.entry-post-thumbnail.above {
min-width: 50% !important;
}
Mes outils de développement ont montré que le CSS "prenait", que la largeur minimale était définie à 50%. Still WP a lancé la même erreur que l'image ne s'affichait pas. Peut-être que le CSS ne le définit pas avant que functions.php exécute wp_get_attachment_image_src, alors cela n'a pas d'importance?
Quelqu'un at-il des indices sur la façon de contourner ce calcul de zéro? J'aimerais vraiment que cela fonctionne avec les images d'arrière-plan, sans avoir à trop écraser le thème parent.
Avec l'aide de @Milo, @NathanJohnson et @prosti, j'ai pu essayer un filtre pour modifier wp_get_attachment_image_src()
. Le code ne génère pas d'erreur, mais il ne supprime pas l'erreur de division et ne fait pas afficher le SVG. C'est l'extrait que j'ai placé dans functions.php. Peut-être que les priorités sont fausses? :
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;
}
Je crois que je dois comprendre comment extraire les informations de largeur du fichier SVG lui-même et les ajouter à la base de données WP avant que functions.php ne lance le calcul à la ligne 771. Si vous savez comment, vos conseils être vraiment apprécié.
Quelques ressources potentiellement utiles
C'est l'en-tête 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">
Je l'ai résolu !!! Le filtre du correctif n ° 3 (ci-dessus) ne fonctionnait pas à cause de la troisième condition de cette instruction if
qui déclenche l'extraction de dimension et la pièce jointe:
if (is_array($image) && preg_match('/\.svg$/i', $image[0]) && $image[1] == 1)
$image[1]
dans la troisième condition est la largeur rapportée du fichier SVG comme WP le voit avant d'entrer dans le filtre. Comme je sais que sa valeur, la largeur, est 0 (d'après "l'erreur de division zéro" décrite ci-dessus), j'ai soupçonné que cette valeur devait être modifiée pour correspondre. J'ai changé le 1
final sur cette condition if
en un 0
et..vila! L’erreur de division s’est dissipée et l’image s’affiche, et joliment pour pouvoir faire de la publicité!
J'ai pu le remarquer car, dans de nombreux forums, des gens se plaignent que les largeurs SVG ne sont pas correctement assignées à des largeurs de 1px. C'était probablement le cas dans certaines versions de WP, mais dans ma médiathèque WP 4.7.2, aucune dimension pour le fichier SVG, pas même 1px
n'est publiée, en tant que dimension. Au lieu de cela, il n'y avait tout simplement pas de métadonnées concernant les dimensions dans mon cas.
Je pense qu'une version flexible du filtre permettrait son application si la largeur est de 1 ou 0, pour les personnes qui ont le problème 1px et pour les personnes comme moi qui ont une largeur de 0. Ci-dessous, j'ai inclus le correctif, en utilisant $image[1] <= 1
as la troisième condition de l'instruction if
au lieu de $image[1] == 1
mais je suppose que vous pourriez aussi utiliser ceci: ( ($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;
}
Merci à tous pour votre aide, c'était vraiment un effort d'équipe!
Il est difficile de deviner exactement quel peut être le problème pour les amateurs de WordPress comme moi, mais depuis que vous m'avez envoyé un ping dans la boucle.
Juste pour mentionner que vous n'avez pas partagé les fichiers de thème ...
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: }
Cette partie avec:
@list( $width, $height ) = getimagesize( $src_file );
On dirait que le problème existe depuis les images SVG ne pas avoir les informations de taille . Ils correspondent juste au conteneur.
Vous pouvez donc créer votre propre version de wp_get_attachment_image_src
où vous pouvez en quelque sorte définir la taille.