Rydde html med saveHTML()

kongen

kongemedlem
Jeg har denne htmlen

Kode:
<p><img src="bolle.jpg" width="300" height="100">bolle er godt</p>

men vil at bilde skal få sin egen <p> slik at det blir

Kode:
<p><img src="bolle.jpg" width="300" height="100"></p>
<p>bolle er godt</p>

hvordan kan php søke gjennom en htmlside, finne bilder, og gjøre om på htmlen hvis nødvendig?
 

adeneo

Medlem
Nå er det jo ikke bare bare, du må altså ta bildet ut av P'en og lage en ny P å sette bildet i som settes inn rett før den andre P'en !

Det er fristende å si at en regex som setter inn "</p><p>" etter bildet elementet er en løsning, men regex til å parse HTML er helt Zalgo.

Du har vel noe sånt da

PHP:
$doc = // html'en din, ->loadHTML eller whatever

$bilder = $doc->getElementsByTagName('img');

foreach ($bilder as $bilde) {
    $p = $doc->createElement('p');
    $bilde->parentNode->parentNode->insertBefore($p, $bilde->parentNode);
    $p->appendChild($bilde);
}

echo $doc->saveHTML();

Jeg gjetter vilt på hvordan HTML'en din ser ut her ?
 

kongen

kongemedlem
Takk :)

Hva hvis htmlen er en blanding på samme side?

Kode:
<p><img src="bolle.jpg" width="300" height="100">bolle er godt</p>
<p>kake er godt<img src="kake.jpg" width="300" height="100"></p>
<p>frokost er bra<img src="mat.jpg" width="300" height="100">middag er bedre</p>

skal bli til

Kode:
<p><img src="bolle.jpg" width="300" height="100"></p>
<p>bolle er godt</p>
<p>kake er godt</p>
<p><img src="kake.jpg" width="300" height="100"></p>
<p>frokost er bra</p>
<p><img src="mat.jpg" width="300" height="100"></p>
<p>middag er bedre</p>
 

adeneo

Medlem
Ehm, det blir vel omtrent det samme, finner bildene og flytter de ut i egne paragrafer, men nå må du plutselig sjekke om teksten er foran eller bak bildene, og plassere bildene deretter ?
 

kongen

kongemedlem
Det blir en krøll hvis <img> ligger inne i en annen <tag>, da blir det en <p> inne i <p>n

Kode:
<p><strong><img src="bolle.jpg">bolle er godt</strong></p>

gir

Kode:
<p><p><img src="bolle.jpg"></p><strong>bolle er godt</strong></p>

men skulle ha gitt

Kode:
<p><img src="bolle.jpg"></p>
<p><strong>bolle er godt</strong></p>
 

adeneo

Medlem
Det er riktig, den finner bare parentNode, den sjekker ikke om det er en P.
Da må man i så fall lage en "closest" funksjon, noe sånt

PHP:
function closest($el, $tag) {
    $tag = strtoupper($tag);
  
    do {
        if ( strtoupper($el->nodeName) === tag ) {
            return $el;
        }
    } while ($el = $el->parentNode);

    return null;
}



$doc = // html'en din, ->loadHTML eller whatever

$bilder = $doc->getElementsByTagName('img');

foreach ($bilder as $bilde) {
    $p       = $doc->createElement('p');
    $closest = closest($bilde, 'p');
  
    $closest->parentNode->insertBefore($p, $closest);
  
    $p->appendChild($bilde);
}

echo $doc->saveHTML();
 

kongen

kongemedlem
Er det mulig å sjekke om bilde er det eneste som er i <p>'en?

PHP:
<p><img src="bolle.jpg"></p>

blir til

PHP:
<p><img src="bolle.jpg"></p>
<p></p>

med en tom <p>
 

adeneo

Medlem
Joa, man kan bruke 'childNodes', som også henter textNodes, og se om det er bare ett element, og så se om det elementet er et bilde

Si man har P'en i en variabel $p, så kan man vel gjøre noe sånt (ikke testet)
PHP:
if ( $p->childNodes->length === 1 && $p->firstChild->nodeName === 'img' )
 

kongen

kongemedlem
Siden står bare å laster og laster. Jeg klarer ikke å se feilen.

PHP:
function closest($el, $tag) {
    $tag = strtoupper($tag);
    do {
        if ( strtoupper($el->nodeName) === $tag ) {
            return $el;
        }
    } while ($el = $el->parentNode);
    return null;
}

$text = '<p><img src="bolle.jpg"></p>';
$doc = new DOMDocument;
$doc->loadHTML($text);

$per = $doc->getElementsByTagName('p');
foreach ($per as $pe) {

if ( $pe->childNodes->length === 1 && $pe->firstChild->nodeName === 'img' ){
} else {
$bilder = $doc->getElementsByTagName('img');

foreach ($bilder as $bilde) {
    $p = $doc->createElement('p');
    $closest = closest($bilde, 'p');
    $closest->parentNode->insertBefore($p, $closest);
    $p->appendChild($bilde);
}

}
}

echo $doc->saveHTML();
 

adeneo

Medlem
Jeg tipper while loopen.

Jeg er vant til at parentNode returnere null dersom det ikke finnes noe element, men det er i javascript, DOMDocument fungerer sikkert litt annerledes.

Det er mulig man må bruke en funksjon i stedet for loopen, eller om det er mulig å gjøre noe sånt (som jeg tviler på)

Kode:
while ( ($el = $el->parentNode)->length !== 0 );
 
Topp