I have two strings I’m outputting to a page
# string 1 <p>paragraph1</p> # string 2 <p>paragraph1</p> <p>paragraph2</p> <p>paragraph3</p>
What I’d like to do is turn them into this
# string 1 <p class="first last">paragraph1</p> # string 2 <p class="first">paragraph1</p> <p>paragraph2</p> <p class="last">paragraph3</p>
I’m essentially trying to replicate the css equivalent of first-child
and last-child
, but I have to physically add them to the tags as I cannot use CSS. The strings are part of a MPDF document and nth-child is not supported on <p>
tags.
I can iterate through the strings easy enough to split the <p>
tags into an array
$dom = new DOMDocument(); $question_paragraphs = array(); $dom->loadHTML($q['quiz_question']); foreach($dom->getElementsByTagName('p') as $node) { $question_paragraphs[] = $dom->saveHTML($node); }
But once I have that array I’m struggling to find a nice clean way to append and prepend the first
and last
class to either end of the array. I end up with lots of ugly loops and array splicing that feels very messy.
I’m wondering if anyone has any slick ways to do this? Thank you 🙂
Edit Note: The two strings are outputting within a while(array)
loop as they’re stored in a database.
Advertisement
Answer
You can index the node list with the item()
method, so you can add the attribute to the first and last elements in the list.
$dom = new DOMDocument(); $question_paragraphs = array(); $dom->loadHTML($q['quiz_question']); $par = $dom->getElementsByTagName('p'); if ($par->length == 1) { $par->item(0)->setAttribute("class", "first last"); } elseif ($par->length > 1) { $par->item(0)->setAttribute("class", "first"); $par->item($par->length - 1)->setAttribute("class", "last"); } foreach($par as $node) { $question_paragraphs[] = $dom->saveHTML($node); }