✅ Nowości, motywy, wtyczki WEB i WordPress. Tutaj dzielimy się wskazówkami i najlepszymi rozwiązaniami dla stron internetowych.

Modyfikuj kontenery obrazów po stronie serwera w WordPress

31

Za każdym razem, gdy tworzysz niestandardowe rozwiązania dla innych osób, możesz mieć do czynienia z drobiazgowymi przypadkami renderowania treści przez WordPress.

Zwykle sprowadza się to do motywu, co najmniej jednej wtyczki lub kombinacji obu. A jeśli musisz pracować z obrazami indywidualnie, może to być wyzwaniem. Problem z nawet próbą napisania takiego posta polega na tym, że trudno jest nawet opisać sytuację, w której możesz potrzebować czegoś takiego.

Mimo to zamierzam zrobić, co w mojej mocy. Oznacza to, że chcę podzielić się sposobem modyfikowania kontenerów obrazów po stronie serwera przed renderowaniem ich po stronie klienta i zrobić to za pomocą biblioteki DOMDocument PHP.

Brzmi jak dużo? Mam nadzieję, że łatwo to rozwiążę.

Zanim przejdziemy do kodu, powiedzmy, że masz je, które renderują obrazy w pojedynczym elemencie akapitu (lub dowolnym typie elementu na poziomie bloku) i musisz owinąć każdy element w jakiś typ klasy, aby móc uzyskać dostęp to za pośrednictwem CSS lub JavaScript.

Gdzie jesteśmy

Na początek powiedzmy, że obrazy renderują się tak:

I musisz je renderować w ten sposób:

Modyfikuj kontenery obrazów po stronie serwera w WordPress

Teraz możesz potrzebować odstępu między nimi lub nie. To naprawdę nie ma znaczenia, ponieważ masz nad tym kontrolę za pośrednictwem CSS. Ale masz kontrolę nad tym, jak to jest przesyłane przez sieć do strony klienta.

Aby to zrobić, potrzebujesz kilku rzeczy:

  • Dostęp do biblioteki DOMDocument PHP,
  • Zrozumienie, jak manipulować treścią za pomocą haka the_content WordPress,
  • Strategia, jak chcesz zawijać obrazy.

Przejdę przez każdy z nich w kodzie, ale wystarczy powiedzieć, że zamierzam zawinąć każdy obraz w element akapitu. Możesz oczywiście zrobić to, co chcesz.

Jak to zrobić

Najpierw upewnij się, że deklarujesz, że używasz treści dokumentu DOM nad swoją klasą :

<?php

namespace Acme;

use DOMDocument;

class AcmeContentSubscriber
{
  // ...
}

Następnie idź dalej i utwórz zaczep do the_content. Sposób, w jaki to zrobisz, będzie zależeć od tego, jak zorganizowałeś swój kod (czy to OOP, czy nie). W tym przykładzie pokażę bardzo prosty przykład, jak to zrobić :

<?php

public function contentSubscriber()
{
  add_action( 'the_content', [$this, 'addImageAttributes']);
}

Następnie będziesz musiał wykonać trochę pracy (z których wszystko jest poniżej, ale poza zakresem tego postu). To zawiera:

  • konwersja kodowania encji HTML,
  • tworzenie instancji dokumentu DOM,
  • ładowanie kodu HTML posta z przychodzącej treści

W kodzie powinno to wyglądać tak :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    // ...
}

Następnie musisz przejść przez  elementy img i upewnić się, że ustawiasz właściwy atrybut. Możesz zdecydować się na użycie klasy, możesz zdecydować się na użycie atrybutu danych lub możesz zdecydować się na użycie czegoś innego. Ta część nie ma znaczenia.

Zwróć uwagę, że dla danego obrazu będziesz chciał sprawdzić, czy następny element nie jest elementem akapitu, ponieważ to właśnie wybieram zawijanie obrazu. Innymi słowy, jeśli następny element nie jest akapitem, zawiniemy go w element akapitu.

Aby to zrobić, szkielet głównej funkcji powinien wyglądać tak :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    $images = $document->getElementsByTagName('img');
    foreach ($images as $image) {
        $image->setAttribute('class', 'acme-iamge');
        if ($image->nextSibling->tagName !== 'p') {
            $this->wrapImage($document, $image);
        }
    }

    // ...
}

Wtedy funkcja odpowiedzialna za faktyczne zawinięcie elementu w elemencie akapitu powinna wyglądać tak :

<?php

/**
 * This function is used to wrap individual images in a paragraph element.
 *
 * @param $document The DOM Document which is to be rendered.
 * @param $image    The image to wrap with the new paragraph element.
 */
private function wrapImage($document, $image)
{
    if (null === $image) {
        return;
    }
    $wrapper = $document->createElement('p');
    $wrapper->setAttribute('class', 'acme-image');

    $image->parentNode->replaceChild($wrapper, $image);
    if (null !== $image) {
        $wrapper->appendChild($image);
    }
}

Pamiętaj, aby przeczytać DocBlock kodu, aby zrozumieć, jak działa funkcja. Mówiąc prosto:

  • akceptuje instancję dokumentu oraz element image,
  • tworzy element akapitu,
  • dodaje atrybut klasy
  • zastępuje oryginalny element obrazu paragrafem,
  • i dodaje obraz jako element podrzędny

A ponieważ oparliśmy obiekt document na metodzie, nie musimy niczego zwracać.

Ostateczna wersja oryginalnej funkcji powinna wyglądać tak :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    $images = $document->getElementsByTagName('img');
    foreach ($images as $image) {
        $image->setAttribute('class', 'acme-image');
        if ($image->nextSibling->tagName !== 'p') {
            $this->wrapImage($document, $image);
        }
    }

  return $document->saveHTML();
}

Twoje wyjście powinno wyglądać jak na powyższym obrazku. Pamiętaj jednak; musisz zwrócić wyniki instancji dokumentu do WordPressa, aby poprawnie renderował kod HTML. I to właśnie  robi funkcja saveHTML w powyższym kodzie.

Źródło nagrywania: tommcfarlin.com

Ta strona korzysta z plików cookie, aby poprawić Twoje wrażenia. Zakładamy, że nie masz nic przeciwko, ale możesz zrezygnować, jeśli chcesz. Akceptuję Więcej szczegółów