Sposoby obsługi renderowania SVG w wordpress?


9

Wraz z postępem przeglądarek internetowych coraz wygodniej mi się korzysta z SVGS podczas kodowania stron internetowych ... szczególnie w przypadku ikon i prostej grafiki, którą można natychmiast zastąpić pngs.

Wygląda na to, że wordpress prawie obsługuje SVGS. Mówię prawie dlatego, że:

  1. Domyślnie nie jest to dozwolony typ pliku w wordpress. Musisz to dodać przed przesłaniem plików SVG

  2. W galerii multimediów nie widać miniatury SVG. (patrz zdjęcie poniżej)

  3. Czasami, gdy dodajesz go do edytora (za pomocą przycisku dodawania multimediów), edytor nie zna rozmiaru svg, więc chociaż dodaje svg jako obraz, ma szerokość i wysokość zero.

  4. Po kliknięciu przycisku „edytuj obraz” w wyskakującym okienku przesyłania multimediów pojawia się komunikat „obraz nie istnieje”. Zobacz zdjęcie poniżej.

Nie mam nic przeciwko pozycji 1 na tej liście, ale czy ktoś odkrył, jak naprawić pozycję 2 3 i 4?

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Aktualizacja o punkcie 1:

Aby zezwolić na nowy typ MIME (taki jak SVG), możesz po prostu dodać hook w functions.php

function allow_new_mime_type($mimes) {

    $mimes['svg'] = 'image/svg+xml';

    return $mimes;
}
add_filter( 'mime_types', 'allow_new_mime_type' );

Teraz powinieneś mieć możliwość przesyłania plików SVG. Więcej informacji można znaleźć w tym samouczku . To rozwiązuje tylko punkt 1, który, jak wspomniałem wcześniej, nie jest dla mnie problemem (chociaż myślę, że domyślnie powinno być dozwolone).

Aktualizacja o punkcie 2:

Zrobiłem trochę kopania i wyśledziłem funkcję, która decyduje, czy załącznik jest obrazem, czy nie. Wygląda na to, że wszystko sprowadza się do tej funkcji w wp-include / post.php

/**
 * Check if the attachment is an image.
 *
 * @since 2.1.0
 *
 * @param int $post_id Attachment ID
 * @return bool
 */
function wp_attachment_is_image( $post_id = 0 ) {
    $post_id = (int) $post_id;
    if ( !$post = get_post( $post_id ) )
        return false;

    if ( !$file = get_attached_file( $post->ID ) )
        return false;

    $ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false;

    $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );

    if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )
        return true;
    return false;
}

Jak widać, w tej funkcji zdefiniowano tablicę poprawnych rozszerzeń obrazu. Nie widzę żadnych filtrów, które mogłyby zostać użyte do modyfikacji tej tablicy. Ale to początek ...

Nie jestem jednak pewien, dlaczego ostatnia instrukcja if zwraca false dla svgs. Nawet jeśli nie dodam rozszerzenia svg do tablicy $ image_exts, pierwszy warunek powinien zwrócić true, prawda?

if ( 'image/' == substr($post->post_mime_type, 0, 6)

To sprawdza, czy „image /” jest równe pierwszej szóstce w typie mime, która dla svg to image / svg + xml (pierwsze sześć to „image /”).

AKTUALIZACJA

Po dalszym badaniu wydaje się, że problem nie dotyczy w ogóle wp_attachment_is_image, ale ponieważ rozmiar obrazu (szerokość i wysokość) nie są dodawane do metadanych załącznika podczas przesyłania SVG. Jest tak, ponieważ funkcją obliczającą użyty obraz jest funkcja php getimagesize (), która nie zwraca rozmiaru obrazu dla SVG. Znalazłem odpowiedź na stackoverflow na temat funkcji getimagesize i tego, jak zachowują się svgs. Zobacz tutaj.


Zainstaluj wtyczkę wsparcia SVG, wyświetla SVG w galerii multimediów - wordpress.org/plugins/svg-support
Nuno Sarmento

Odpowiedzi:


10

Spójrz na wp_prepare_attachment_for_js()to, co gromadzi metadane załączników do wykorzystania na stronach Media. Filtr tytułowy pozwala nam dodawać lub zmieniać metadane.

Poniższy przykład można upuścić do functions.php. Uwaga: wymaga to obsługi SimpleXML w PHP.

function common_svg_media_thumbnails($response, $attachment, $meta){
    if($response['type'] === 'image' && $response['subtype'] === 'svg+xml' && class_exists('SimpleXMLElement'))
    {
        try {
            $path = get_attached_file($attachment->ID);
            if(@file_exists($path))
            {
                $svg = new SimpleXMLElement(@file_get_contents($path));
                $src = $response['url'];
                $width = (int) $svg['width'];
                $height = (int) $svg['height'];

                //media gallery
                $response['image'] = compact( 'src', 'width', 'height' );
                $response['thumb'] = compact( 'src', 'width', 'height' );

                //media single
                $response['sizes']['full'] = array(
                    'height'        => $height,
                    'width'         => $width,
                    'url'           => $src,
                    'orientation'   => $height > $width ? 'portrait' : 'landscape',
                );
            }
        }
        catch(Exception $e){}
    }

    return $response;
}
add_filter('wp_prepare_attachment_for_js', 'common_svg_media_thumbnails', 10, 3);

2

Nie jest to coś, co łatwo będzie „włamać się” za pomocą wtyczki lub jakiegoś małego zestawu kodu.

Krótko mówiąc, SVG w zasadzie nie są „obrazami” w sensie wszystkich obrazów, które pojawiły się przed nim. Pliki SVG są obrazami wektorowymi i są pierwszymi, które zapewniają prawdziwą przyczepność w Internecie.

Wszystkie obrazy wcześniej były oparte na bitmapach. System obsługi obrazów WordPress został napisany specjalnie, aby sobie z nimi poradzić, a ten nieodłączny projekt znajduje się w każdym punkcie systemu.

Jest to podstawowe założenie, że na przykład obrazy mają szerokości i wysokości. Pliki SVG nie mają, mogą mieć dowolny rozmiar. Istnieje cały podstawowy „edytor” obrazów wbudowanych w WordPress, którego żadna funkcjonalność nie może tak naprawdę mieć zastosowania do plików SVG.

System multimedialny jest powoli przebudowywany, z naciskiem na „powoli”. Należy zachować wiele kompatybilności wstecznej i wprowadzić nowe projekty. Ponadto większość osób jest znacznie bardziej zainteresowana obsługą wideo, audio i list odtwarzania. Po zakończeniu tej przeprojektowania, a fragmenty biblioteki stają się bardziej abstrakcyjne, z czasem tego rodzaju rzeczy będą łatwiejsze do obsługi. Ale jeszcze jej nie ma i nie potrwa to długo. Właśnie dlatego typ MIME SVG nie jest obsługiwany, ponieważ dodanie tego typu MIME, dopóki wszystkie leżące u jego podstaw elementy nie zadziałają, byłoby drogą do złamania.

W przypadku plików SVG wartość wp_attachment_is_imagepowinna zwracać wartość false, ponieważ wp_attachment_is_imagesłuży ona do określenia, czy przycisk edytora ma być pokazywany, oraz czy image_downsizepróbuje zmienić rozmiar obrazu na miniatury i tym podobne. Żadne z nich i tak nie działałoby w przypadku plików SVG. Aby poprawnie obsługiwać pliki SVG, należy napisać nowy system do dodawania metadanych dla tych obrazów całkowicie, a następnie dodać obsługę tego we wszystkich miejscach, w których można używać metadanych. Jak możesz sobie wyobrazić, nie jest to mała praca.


1
Pliki SVG mają rozmiar (rzutnia i pole widoku), są po prostu bardziej „wirtualne” niż ustalone wymiary bitmap zależne od pikseli.
Rarst

1

Już po przeczytaniu źródła (nie testowaniu) widzę, że rozszerzenie musi pasować:

if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )

który czyta się jako (pseudo kod)

if image/jest pierwszymi 6 znakami we właściwości $ post obiekt post_mime_type LUB istnieje rozszerzenie LUB importto właściwość $ post objects post_mime_type ORAZ bieżącym rozszerzeniem pliku jest (Array)

A to oznacza, że ​​ostatnie stwierdzenie zawsze decyduje, czy ifokaże się prawdą, czy nie.

Z tego, co mogę przeczytać get_attached_file(), jest filtr, który pozwoliłby sfałszować rozszerzenie:

return apply_filters( 'get_attached_file', $file, $attachment_id );

Innymi słowy, możesz spróbować zwrócić ten sam plik, ale z innym rozszerzeniem. To nie koliduje z innymi częściami, ponieważ wp_attachment_is_image()właśnie powraca bool.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.