HTML supports (in most browsers) the contentEditable attribute which allows you to dynamically change a web page(s) content by simply editing the page, think of it like a WYSIWYG editor , but built-in to the browser. The purpose of this post is to show you how you can use this to create a simple, but powerful editing system using just PHP and a modern browser. All this code can be found in my [icon name=”git” class=”” unprefixed_class=””] GitHub Repository phpContentEdit
I’ll demonstrate how using just PHP , a modern browser (that supports ContentEditable) and a file system you can update your webpages easily and quickly and with the proper security allow only registered users to make the changes. This example is most a proof of content, and is intended as a starting point for more sophisticated content editing capabilities.
General Steps for using PHP with ContentEditable
Basically, the script is broken up into two parts.
- The plain HTML file we want to edit , which holds our content, we’ll call this content.html
- The PHP script named index.php which reads and write the content.html and saves the changes
We first begin by just reading and displaying the content.html , and we also have a few {{placeholders}} inside content.html to replace things like title or JavaScript or action , basically anything dynamic, since remember the content.html is just a template file. Here’s an example of what the top of the index.php looks like.
<?php // Change the following to suit your environment $basename= pathinfo(basename($_SERVER['SCRIPT_NAME']), PATHINFO_FILENAME); $html_filename="content.html"; //html file that holds content, and is to be updated $server_write_hmtl=$_SERVER['PHP_SELF']; // PHP server page that writes the content $secret_pw="admin" ; //secrete password to allow editable content // End of configurable code error_reporting(E_ALL); ini_set('display_errors', 'On'); //useful for debugging ob_start(); //start buffering the content session_start(); // start this session date_default_timezone_set('America/New_York'); //Enable timezone //Load in the corresponding HTML template file by the same name $page_html = file_get_contents($html_filename); //load in our html content with proper placeholders
The content.html in this example uses Bootstrap CSS to make it easier to style the page, but really any valid HTML will work. We also add a little allowEdit javascript within the content.html to basically put it into edit mode. This examples uses a very simplistic password prompt, but its recommended you secure the page more carefully for production systems. The prompt can be initiated by a button (as in this example) or via a secret queryString parameter, use your best judgement how to enabled editing
<input type="hidden" name="pw" value="" id="pw"><button type="submit" class="btn btn-primary" onclick="return allowEdit()"> Edit </button> <script> function allowEdit() { var result= prompt('Credentials for editing. Make more secure. This is for demo purposes.'); document.getElementById('pw').value=result; return result; } </script>
After the password prompt, we send the request back to the same index.php which checks that the user supplied password against our “secret” hash and if they match, reloads the content.html replacing the <div class="editable" id="ce-1">
with tags with <div class="editable" contentEditabe="true" id="ce-1">
This then allows the user to make the edits inside the browser.
The we have a dynamically generated JavaScript Ajax function which attaches an event-handler to the onBlur event of the editable class attributes and grabs the id for that content and sends the changes back through the server.
<script> $('.editable').blur(function(){ var myTxt = $(this).html(); var myid = $(this).attr('id'); console.log("Updating content: "+myTxt.trim() ); console.log("content ATTR: "+myid); $.ajax({ type: 'post', url: '/PHP/phpContentEdit/index.php', data: 'content=' +myTxt+"&id="+myid+"&action=write" }); }); </script>
Finally , the index.php script gets the changes, checks its session to see that it’s authorized to write the changes to the disk, and then uses the
new DOMDocument();
and $xpath->query("//*[@id='".$id."']"); //search for our id
To walk the HTML DOM And update the proper id tags and replace the content on disk, here’s what the entire block of code looks like.
//Ok lets re-write the content for this page if ( isset($_REQUEST['action']) && $_REQUEST['action']=="write" && isset($_REQUEST['id']) ) // { //REQUIRES THAT DOMDocument is available //https://www.php.net/manual/en/class.domdocument.php //in order to properly parse HTML file and append to it. $doc = new DOMDocument(); //instantiate the HTML $doc->loadHTML($page_html); //load the HTML into the DomDocument Parser $id=$_REQUEST['id']; $replacement_html = htmlspecialchars( trim($_REQUEST['content']) ); echo "Editing content //*[@id='".$id."']"; //debug messages can be remove echo "\n Replacing with contnet \n"; //debug messages can be remove echo $replacement_html ; //Now walk the matching Nodes and REPLACE with the new fragment $xpath = new DOMXPath($doc); //setup an Xpath Query object $nodes = $xpath->query("//*[@id='".$id."']"); //search for our id foreach($nodes as $node) { $newnode = $doc->createDocumentFragment(); if ( isset($replacement_html) ) { $newnode->appendXML($replacement_html); //new content // $node->appendChild($newnode); //replace the existing content $node->parentNode->replaceChild($newnode, $node); } } //write the update page (Entire Page back to disk) if (is_writable($html_filename)) { $bytes= $doc->saveHTMLFile($html_filename); echo "\n Success wrote $html_filename with $bytes bytes \n"; } else die("File $html_filename cannot not be written to check permissions"); //return status and exit here. die("\n Success AJAX Function write Content"); }
Page Security considerations
As I mentioned before , using this technique on a live site, with minimal security considerations is just inviting trouble, since, we’re allowing folks to edit our file system natively we are exposing our site to some potential damage. So to minimize that we may want to sanitize the edited HTML prior to writing it to disk, escaping any offending or malicious user input.
Best use cases for ContentEdit
ContentEdit can be used in its raw form as I outlined in this post, but it can also work with WYSIWYG editors so if you want to allow users to style the HMTL and be able to create more intricate page layouts and formatting, then be sure to use one of the many HTML WYSIWYG editors and then just save its changes.
Demo Page
Go to my Github and download the example and throw it up on your PHP server to see it in action.
Can I use this on any web page , or does the conteditsble need to be a specific format?
Nelson, it should work on any web page, the only requirements are that the HTML page is writable (by the web server ) and that its wrapped inside teh
can you provide the link to the demo?
Code is up on Github, I cant easily put a live demo as it would require to many permissions changes on this blog to secure the page properly
thankyou! Could i add this code in the same document as my html?
Yes,
gg