it-swarm.com.de

SVG-Dimensionen können nicht extrahiert und festgelegt werden

Bisher hatte ich keine Probleme mit den Miniaturansichten des Hintergrundbilds in meinem Thema. Nun, da ich versuche, ein SVG als das vorgestellte Bild zu verwenden, bricht etwas zusammen. Das Problem scheint mit der Breite der SVGs zu zusammenhängen, die von wp_get_attachment_image_src() als Null zurückgegeben werden. Ich versuche also herauszufinden, wie die Breiten- und Höheninformationen aus der SVG extrahiert und dann auf die entsprechenden Werte in den SVG-Datenbankfeldern gesetzt werden, was sich nicht als einfach herausstellt.

Hinweis: Es gibt keine generellen Probleme beim Hochladen oder Rendern von SVGs. Sie werden in meinem Logo gut angezeigt.

Der Fehler und der Code: Beweis der Breite Null

Dies ist der Fehler, den Wordpress auf der Seite auslöst: Warning: Division by zero in /wp-content/themes/tesseract/functions.php on line 771

Dies ist der Code in functions.php vor dem Fehler (in Zeile 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 ****/

Sie können sehen, dass es eine Unterteilung mit $wr als Nenner gibt. Es scheint, dass $wr als Null berechnet wird, weil sein einziger nicht konstanter Faktor, $w, ebenfalls Null ist (der andere Faktor ist 720, es kann also keine Schuld sein). Der Wert von $w wird durch $thumbnail[1] bestimmt. Der Wert von $thumbnail[1] wird in Zeile 763 mit folgendem Code festgelegt:

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

Und nach dem dem Codex ist der zweite Wert im Rückgabearray der Funktion wp_get_attachment_image_src (d. H. $thumbnail[1]) tatsächlich die Breite des Thumbnails. Dieser Wert scheint Null zu sein, da es sich um denselben Wert handelt wie $w, der in der Tat den Nenner in Zeile 771 darstellt. :(

Wichtiger Hinweis: Mein Theme implementiert Thumbnails als Hintergrundbilder

Das von mir verwendete übergeordnete Thema "Tesseract" platziert ausgewählte Bilder als Hintergrundbilder von Ankern/<a>-Elementen, anstatt sie als <img>-Elemente zu platzieren. Ich glaube nicht, dass dies die Ursache des Problems ist, aber wenn sie Lösungen anbieten, sollten sie mit Hintergrundbildern kompatibel sein, nicht mit <img> Objekten.

Fix Nr. 1 konnte nicht angepasst werden:

Ich habe diese Webseite gefunden, die eine Lösung für Probleme bei der Verwendung von SVGs als vorgestellte Bilder bietet. Dies deutet darauf hin, dass das Problem mit der Berechnung der Breite zusammenhängt. Ich kann dieses Update jedoch nicht anwenden, da es für ein img-Element mit einer SVG-Datei als src gilt. Ich habe ein <a>-Element, dessen SVG-Position auf den background-image-url festgelegt ist.

Das ist die Lösung

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');

Fix # 2 (min-width via CSS) hat nicht funktioniert

Basierend auf der Idee, die ich auf der obigen Seite erhalten habe, dass die Breite des das Problem sein könnte, habe ich versucht, eine minimale Breite von 50% einzustellen, indem ich nur CSS für den <a> verwendete. Hier ist der Code:

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

Meine Entwicklertools zeigten, dass das CSS "nahm", dass die min-width auf 50% gesetzt wurde. Trotzdem hat WP denselben Fehler ausgegeben, den das Bild nicht angezeigt hat. Vielleicht setzt das CSS es nicht bevor functions.php wp_get_attachment_image_src ausführt, also spielt es keine Rolle?

Hat jemand eine Ahnung, wie man diese Null-Berechnung umgeht? Ich möchte das wirklich mit den Hintergrundbildern zum Laufen bringen, ohne zu viel des übergeordneten Themas überschreiben zu müssen.

Fix # 3 (Filter einbinden) hat nicht funktioniert.

Mit Hilfe von @Milo, @NathanJohnson und @prosti konnte ich einen Filter ausprobieren, um wp_get_attachment_image_src() zu ändern. Der Code erzeugt keinen Fehler, beseitigt jedoch weder den Divisionsfehler noch lässt er die SVG-Datei anzeigen. Dies ist das Snippet, das ich in functions.php platziert habe. Vielleicht sind die Prioritäten falsch? :

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;
    } 

Die Quintessenz:

Ich glaube, ich muss herausfinden, wie die Breiteninformationen aus der SVG-Datei selbst extrahiert und zur Datenbank WP hinzugefügt werden, bevor functions.php die Berechnung in Zeile 771 ausführt. Wenn Sie wissen, wie, würde Ihre Anleitung wirklich geschätzt werden.

Einige potenziell hilfreiche Ressourcen

  • Diese Frage scheint hilfreiche Informationen zu haben, und das von @Josh dort bereitgestellte Snippet hat es mir ermöglicht, meine SVGs endlich in der Medienbibliothek anzuzeigen, aber das gezeigte Bild ist immer noch defekt.
  • Diese Frage scheint einige XML-basierte Lösungen zu haben, aber ich weiß nicht, wie ich sie an WP anpassen soll.
  • Ein Kommentator weiter unten hat mich auch auf diesen Filter hingewiesen, der relevant zu sein scheint.

Der Header der SVG-Datei

Dies ist der SVG-Header:

<?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">
7

Ich habe es gelöst !!! Der Filter in Fix 3 (oben) hat aufgrund der dritten Bedingung dieser if-Anweisung, die das Extrahieren und Anhängen von Dimensionen auslöst, nicht funktioniert:

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

$image[1] in der dritten Bedingung ist die gemeldete Breite der SVG-Datei, die WP sieht, bevor sie in den Filter eintritt. Da ich weiß, dass sein Wert, die Breite, 0 ist (aufgrund des oben beschriebenen "Nullteilungsfehlers"), habe ich vermutet, dass dieser Wert geändert werden muss, um ihm zu entsprechen. Ich habe den endgültigen 1 für diese if Bedingung in einen 0 und..voila geändert! Der Teilungsfehler ist verschwunden und das Bild wird angezeigt.

Ich konnte dies feststellen, weil sich in vielen Foren Leute darüber beschweren, dass SVGs fälschlicherweise Breiten von 1px zugewiesen bekommen. Dies war wahrscheinlich in einigen Versionen von WP der Fall, aber in meiner Medienbibliothek WP 4.7.2 wird keine Dimension für die SVG, nicht einmal 1px, als Dimension gepostet. Stattdessen gab es in meinem Fall einfach keine Metadaten zu Dimensionen.

Ich denke, eine flexible Version des Filters würde es ermöglichen, ihn anzuwenden, wenn die Breite 1 oder 0 ist, für Leute, die das 1px-Problem hatten, und für Leute wie mich, die eine Breite von 0 hatten. Unten habe ich den Fix mit $image[1] <= 1as eingefügt die dritte Bedingung der if-Anweisung anstelle von $image[1] == 1, aber ich nehme an, Sie könnten dies auch verwenden: ( ($image[1] == 0) || ($image[1] == 1) )

Der Arbeitsfilter

 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;
} 

Vielen Dank an alle für Ihre Hilfe, es war wirklich eine Teamleistung!

6

Es ist schwer zu erraten, was genau das Problem für den WordPress-Enthusiasten wie mich sein könnte, aber seitdem du mich in den Loop gepingt hast ...

Nur um zu erwähnen, dass Sie die Themendateien nicht freigegeben haben ...

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:    }

Dieser Teil mit:

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

Sieht nach dem Problem aus, da SVG-Bilder keine Größenangabe haben . Sie passen einfach in den Container.

Sie können also Ihre eigene Version von wp_get_attachment_image_src erstellen, in der Sie die Größe irgendwie festlegen können.

2
prosti