Kui loote kohandatud lahendusi teistele inimestele, võib juhtuda, et peate tegelema nüansirikaste juhtumitega, kuidas WordPress sisu renderdab.
Tavaliselt taandub see teemale, vähemalt ühele pistikprogrammile või mõlema kombinatsioonile. Ja kui teil on vaja töötada piltidega eraldi, võib see olla väike väljakutse. Isegi sellise postituse kirjutamise proovimisel on probleem selles, et isegi raske on kirjeldada olukorda, kus teil võib midagi sellist vaja minna.
Sellegipoolest annan ma endast parima. See tähendab, et ma tahan jagada, kuidas muuta pildikonteinereid serveri poolel enne nende renderdamist kliendi poolel ja teha seda PHP DOMDocument teegi abil.
Kõlab nagu palju? Loodetavasti saan selle piisavalt lihtsalt lahti.
Enne koodiga tutvumist oletame, et teil on need, mis renderdavad pilte ühes lõiguelemendis (või mis tahes tüüpi plokitaseme elemendis) ja peate iga elemendi mähkima teatud tüüpi klassi, et teil oleks juurdepääs seda CSS-i või JavaScripti kaudu.
Kus me oleme
Alustuseks oletame, et pildid renderdatakse järgmiselt:
Ja peate need renderdama järgmiselt:
Nüüd võib nende vahel ruumi vaja minna või mitte. See pole tegelikult oluline, sest teil on CSS-i kaudu kontroll selle üle. Kuid teil on kontroll selle üle, kuidas see juhtme kaudu kliendi poolele saadetakse.
Selleks vajate mõnda asja:
- Juurdepääs PHP DOMDocumenti teegile,
- WordPressi konksu the_content kaudu sisuga manipuleerimise mõistmine ,
- Strateegia selle kohta, kuidas soovite pilte pakkida.
Ma käsitlen kõiki neid koodis, kuid piisab, kui öelda, et mähkin iga pildi lõigu elemendiks. Ilmselgelt saate teha seda, mida soovite.
Kuidas seda teha
Esiteks veenduge, et olete deklareerinud, et kasutate oma klassi kohal oleva DOM-dokumendi sisu :
<?php
namespace Acme;
use DOMDocument;
class AcmeContentSubscriber
{
// ...
}
Järgmisena jätkake ja looge konks saidile_content. Kuidas seda teha, sõltub sellest, kuidas olete oma koodi korraldanud (olgu see siis OOP või mitte). Selle näite puhul näitan väga lihtsat näidet selle kohta, kuidas seda teha :
<?php
public function contentSubscriber()
{
add_action( 'the_content', [$this, 'addImageAttributes']);
}
Pärast seda peate natuke tööd tegema (kõik see on allpool, kuid väljaspool selle postituse ulatust). See sisaldab:
- HTML-üksuste kodeeringu teisendamine,
- DOM-dokumendi eksemplari loomine,
- postituse HTML-i laadimine sissetulevast sisust
Koodis peaks see välja nägema järgmine :
<?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));
// ...
}
Järgmiseks peate läbima img – elemendid ja veenduma, et määrate õige atribuudi. Võite valida klassi kasutamise, andmeatribuudi kasutamise või millegi muu kasutamise. See osa ei oma tähtsust.
Pange tähele, et antud pildi puhul peaksite kontrollima, et järgmine element ei oleks lõiguelement, kuna valin pildi ümber selle. Teisisõnu, kui järgmine element ei ole lõik, siis mähime elemendi lõigu elemendiks.
Selleks peaks põhifunktsiooni skelett välja nägema järgmine :
<?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);
}
}
// ...
}
Siis peaks funktsioon, mis vastutab elemendi tegelikult lõiguelemendis mähkimise eest, välja nägema järgmine :
<?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);
}
}
Funktsiooni toimimise mõistmiseks lugege kindlasti koodi DocBlocki. Lihtsamalt öeldes:
- see aktsepteerib dokumendi eksemplari ja pildielementi,
- loob lõigu elemendi,
- lisab klassi atribuudi
- asendab algse pildielemendi lõiguga,
- ja lisab pildi alamelemendina
Ja kuna oleme meetodi aluseks võtnud dokumendiobjekti, ei pea me midagi tagastama.
Algse funktsiooni lõplik versioon peaks välja nägema järgmine :
<?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();
}
Ja teie väljund peaks välja nägema nagu ülaltoodud pildil. Pidage siiski meeles; peate dokumendi eksemplari tulemused WordPressile tagastama, et see renderdaks HTML-i õigesti. Ja seda teeb ülaltoodud koodis funktsioon saveHTML .
