Sometimes there might arise a situation to alter the stored HTML of the database to display on the fly to the user or you might want to play around with XML from PHP. This is where the DOMDocument
of PHP comes to place.
NOTE: No need for any external libraries. It's built-in hidden gem of PHP.
We will be covering the following topics
Basically, I faced the problem when writing code for the existing blog to AMP version blog.
I had my articles code snippets, images, iframes, and other HTML elements stored inside the database. These HTML elements are not directly compatible with AMP HTML and have to be replaced, common tags that I had to replace are as follows
img -> amp-img
iframe -> amp-iframe
Not only elements even a few attributes
of HTML elements were not supported.
I was earlier working on WYSIWYG editors and stumbled upon PHP's hidden gem ie, DomDocument.
DomDocument object is similar to that of your Javascript DOM. In case if you have earlier worked with Javascript DOM manipulation then it will be really simpler for you.
DOMDocument()
)You can start playing around with PHP DOMDocument by initializing it as follows
$dom = new \DOMDocument();
loadHtml
/ loadXml
)Now, we have to load the HTML or XML document we would like to playaround.
$dom->loadHtml($htmlCode); /** For HTML Parsing */
$dom->loadXml($xmlCode); /** For XML Parsing */
Since I have stored HTML snippet code for articles inside my database I will load it as follows
$post = Post::with(['user'])->where(['slug' => $slug])->first();
$dom = new \DOMDocument();
$dom->loadHtml($post->body);
getElementsByTagName
)Basically I have my code snippets inside pre
HTML tag so I can use the following ways to get all the pre
elements
$codeSnippets = $dom->getElementsByTagName('pre');
removeAttribute
)Since HTML spellcheck
attribute is not supported by AMP HTML we need to remove it while displaying it in the AMP view page.
$post = Post::with(['user'])->where(['slug' => $slug])->first();
$dom = new \DOMDocument();
$dom->loadHtml($post->body);
$codeSnippets = $dom->getElementsByTagName('pre');
foreach ($codeSnippets as $code) {
$code->removeAttribute('spellcheck');
}
Similarly we can remove other attributes from different element too as follows
$contentEditables = $dom->getElementsByTagName('div');
foreach ($contentEditables as $contentEditable) {
$contentEditable->removeAttribute('contenteditable');
}
setAttribute
)Similar to remove attribute we can even set the attribute like the following
/** Set the Image Attribute */
$image->setAttribute('test', 'testvalue');
getAttribute
)If we need any values of the element we can use getAttribute
to get the value of the attribute and then we can play around as follows
/** Get the Image Attribute */
$imageSrc = $image->getAttribute('src');
parentNode
)If we need the current element parent node then we can fetch it as follows
$parentNode = $image->parentNode;
replaceChild
)We can easily replace the existing Child nodes of the parent element with the help of the following
$parentNode->replaceChild($newElement, $oldElement);
Now, we got our basics strong. Let's implement the same in our project
$post = Post::with(['user'])->where(['slug' => $slug])->first();
$dom = new \DOMDocument();
$dom->loadHtml($post->body);
/** Get all the images */
$images = $dom->getElementsByTagName('img');
/** Get the lengths of the images to perform element replacing */
$imagesLength = $images->length;
for ($i = 0; $i < $imagesLength; $i++) {
$image=$images->item(0);
/** Get the Image Attributes */
$imageSrc = $image->getAttribute('src');
$imageAlt = $image->getAttribute('alt');
/** Get the parent node of image so that I can append the new amp-img */
$parentNode = $image->parentNode;
/** Creating new element */
$ampImage = $image->ownerDocument->createElement('amp-img');
$ampImage->setAttribute('src', $imageSrc);
$ampImage->setAttribute('width', '400');
$ampImage->setAttribute('height', '300');
$ampImage->setAttribute('layout', 'responsive');
$ampImage->setAttribute('alt', $imageAlt);
/** Replace child element */
$parentNode->replaceChild($ampImage, $image);
}
There is nothing to explain here as I have done that part in step 2.
If you are new to AMP then don't forget to check out the following articles
Install Apache Web Server On Ubuntu 20.04 / Linux & Manage It
Generate Sitemap in PHP Laravel
Unable to prepare route [{fallbackPlaceholder}] for serialization. Uses Closure In Laravel
Increase Session Timeout In Laravel
PHP file_put_contents failed to open stream: Permission denied
Resolve 404 Not Found In NGINX
Free SSL Certificate In cPanel With ZeroSSL & Certbot
Basic Server Security Setup For Ubuntu / Linux
Free Live Chat Integration Using TAWK.IO
Lazy Load Images In Chrome With This Simple Trick
Send SMS With Amazon SNS (Simple Notification Service) Using PHP
Supervisor For Laravel Queue Scheduling
Install Packages Parallel For Faster Development In Composer