Adding style tags to head with PHP DOMDocument
Asked Answered
M

3

7

I want to create and add a set of <style> tags to the head tags of an HTML document.

I know I can start out like this:

$url_contents = file_get_contents('http://example.com');
$dom = new DOMDocument;
$dom->loadHTML($url_contents);

$new_elm = $dom->createElement('style', 'css goes here');
$elm_type_attr = $dom->createAttribute('type');
$elm_type_attr->value = 'text/css';
$new_elm->appendChild($elm_type_attr);

Now, I also know that I can add the new style tags to the HTML like this:

$dom->appendChild($ss_elm);
$dom->saveHTML();

However, this would create the following scenario:

<html>
<!--Lots of HTML here-->
</html><style type="text/css">css goes here</style>

The above is essentially pointless; the CSS is not parsed and just sits there.

I found this solution online (obviously didn't work):

$head = $dom->getElementsByTagName('head');
$head->appendChild($new_elm);
$dom->saveHTML();

Thanks for the help!!

EDIT:

Is it possible?

Mcelroy answered 11/9, 2012 at 22:10 Comment(2)
What do you mean by "didn't work"? Also, you should probably get an error when you do $new_elm->appendChild($elm_type_attr); because DOMElement doesn't have an appendChild method.Apostolate
When I say didn't work, I mean instead of displaying the edited HTML, there's just a blank page. However, $new_elm->appendChild(); works. Is there an alternative I should use?Mcelroy
C
6

getElementsByTagName returns an array of nodes, so probably try

 $head->[0]->appendChild($new_elm);
Cantabile answered 11/9, 2012 at 22:24 Comment(1)
Patouche said it bit more precisely it's returning DOMNodeList object which behaves like array (regarding this you can check Iterators and ArrayObject which are SPL objects), thats why you can access it like array and also iterate over itCantabile
R
6
$head = $dom->getElementsByTagName('head');

Return a DOMNodeList. I think it will be better to get the first element like this

 $head = $dom->getElementsByTagName('head')->item(0);

So $head will be a DOMNode object. So you can use the appendChild method.

Ribbonfish answered 11/9, 2012 at 22:24 Comment(0)
H
4

This is the solution that worked for me

// Create new <style> tag containing given CSS
$new_elm = $dom->createElement('style', 'css goes here');
$new_elm->setAttribute('type', 'text/css');

// Inject the new <style> Tag in the document head
$head = $dom->getElementsByTagName('head')->item(0);
$head->appendChild($new_elm);

You can also add this line at the end to have a clean indentation

// Add a line break between </style> and </head> (optional)
$head->insertBefore($dom->createTextNode("\n"));
Homochromatic answered 20/10, 2020 at 15:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.