PHP Dom - Inserting an LI into a UL

Hi, i am using a 3rd party PHP library (wordpress :smiley: ) that returns an unordered list via a string, which is HTML as shown below:


<ul>
  <li class="page_item page-item-77"><a href="#" title="About">About</a></li>
  <li class="page_item page-item-22"><a href="#" title="Contact Us">Contact Us</a></li>
  <li class="page_item page-item-80"><a href="#" title="Why">Why</a></li>
</ul>

I would like to learn two things:

  1. How to insert a new List Item element at a certain numbered list position (i.e. before the first element, after the second element etc).

  2. Find an element by LI title, and then i can apply the same code from the first question to insert before or after.

  3. How would i save the changed HTML and echo it out?

I have never used DOM let alone PHP DOM so is taking me a lot of head scratching :smiley: so far i have managed to get the following code:


$children = wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0');
$doc = new DOMDocument();
$doc->loadHTML($children);

As you can see i still have a long way to go, any advice or tips greatly appreciated.

Many thanks in advance,

Chris

done a bit of googling, seems DOM needs an innerHTML function which can be reproduced with the following code:

$Body = $doc->getElementsByTagName(β€˜ul’)->item(0)->ownerDocument->documentElement->firstChild->firstChild;
$Document = new DOMDocument();
$Document->appendChild($Document->importNode($Body,true));

Many thanks guys.

Cheers,

Chris

Thanks Jaanboy and Anthony, really appreciate it! :slight_smile:

It is working and its indeed adding new LI to the list. However I am then echoing this UL list html out and only need to echo the UL itself and not the

<!DOCTYPE html PUBLIC β€œ-//W3C//DTD HTML 4.0 Transitional//EN” β€œhttp://www.w3.org/TR/REC-html40/loose.dtd”>
<html><body>

and

</body></html>

tags, since these already exist in my document. Is it possible just to get the HTML for the single UL element?

Thanks again, i am almost there thanks to you.

Cheers,

Chris


<?php
$list = '
<ul>
  <li>Geoffery</li>
  <li>George</li>
  <li>Bungle</li>
</ul>
';

$dom = new DOMDocument();
$dom->loadHTML($list);
$dom->getElementsByTagName('ul')->item(0)->insertBefore(
  $dom->createElement('li', 'Zippy'),
  $dom->getElementsByTagName('li')->item(2)
);
echo $dom->saveHTML();

/*
  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
  <html>
    <body>
      <ul>
        <li>Geoffery</li>
        <li>George</li>
        <li>Zippy</li>
        <li>Bungle</li>
      </ul>
    </body>
  </html>
*/

Whipped up an example for you:

$doc = new DOMDocument();
$doc->loadHTML($children);

// Navigate to the ul
$ul = $doc->getElementsByTagName('ul')->item(0);

// 0 for the first li, etc..
$node = $ul->childNodes->item(0);

// Create the li
$li = $doc->createElement('li');

// Create the link (products for the example)
$a = $doc->createElement('a', 'Products');
$a->setAttribute('class', 'page_item');
$a->setAttribute('href', '#');
$a->setAttribute('title', 'Products');

// Add it to the li
$li->appendChild($a);

// Add to the list before the specified item
// To add at the end of the list, use a non-existent node ie: $ul->childNodes->item(100)
$ul->insertBefore($li, $node);

// Display
echo $doc->saveHTML();

For part 2 I’m not sure. Probably using xpath.

Anyway, hope that helps a bit :wink: