2022-01-27
Integrating CKEditor into your web site

Up until recently, my Drupal web site kept sending me emails informing me that support for Drupal 8 was being discontinued and that I needed to upgrade to Drupal 9. Unfortunately, I didn't succeed in migrating from Drupal 8 to Drupal 9 from the first try. Confronted with different technical issues, I decided to stop using Drupal altogether. I was tired of having to upgrade to a newer version on a regular version, just because I wanted the ease of use of being able to create and update content for my web site. The most "special" Drupal features I used were taxonomy—the possibility to tag a blog post—and a calendar—for which I used a barely supported add-on. The forced update to Drupal 9 made me decide that it would be much easier to write my own, extremely simple CMS, one that exactly fit my needs and nothing more.

This turned out to be much easier than I imagined. I wrote a database query to extract all my old blog posts from the Drupal database, along with the title, type, language, date, and /path of each post. I added an extra field that allowed me to define keyword metadata for each post. I then wrote a .htaccess file that redirected requests to a script that fetched the blog posts based on that /path. I created a separate table with topics and a table that linked topics with posts. I guess I spent less time on writing that code than I would have spent migrating from Drupal 8 to Drupal 9.

The more difficult part was how to create the functionality to create new posts and edit existing posts, but once I understood how to use CKEditor, I also succeeded in writing that part of my CMS. I downloaded the WYSIWYG editor and I copied the files to my website. I didn't even look at that code.

I created a page that contained this script in the <head>-section of my page:

<script src="/ckeditor/ckeditor.js"></script>

I added a <form> to the <body>-section:

<form id="editorform">
    <textarea name="editor" id="editor" rows="10" cols="80">
    <!-- Code that shows the content of an existing blog post -->
    </textarea>
    <script>CKEDITOR.replace('editor');</script>
    <button onclick="submitData()">Save Content</button>
</form>

I gave the form the name editorform, and it contains a <textarea> and a <button>. If I use the form for editing an existing post instead of creating a new one, I add the existing content in the text area (the object I gave the name editor as id). With a small snippet of JavaScript, I instruct CKEditor to replace the text area with a WYSIWIG editor. Just test this and you'll see that CKEditor works its magic when you do this.

I had a harder time trying to figure out how to send the content created with the editor to my server. Eventually, I went for a solution with a button that calls a JavaScript method submitData() when clicked. This is how I implemented this method:

function submitData() {
    const form = document.createElement('form');
    form.method = 'post';
    form.action = 'process_post.php';
    const data = document.createElement('input');
    data.type = 'hidden';
    data.name = 'data';
    data.value = CKEDITOR.instances.editor.getData();
    form.appendChild(data);
    const id = document.createElement('input');
    id.type = 'hidden';
    id.name = 'id';
    id.value = '<?php echo $id; ?>';
    form.appendChild(id);
    document.body.removeChild(document.getElementById('editorform'));
    document.body.append(form);
    form.submit();
}

First I create a new element of type <form>. I configure this form in such a way that it will POST its form fields to the server-side script process_post.php.

I create two <input> fields for this form:

I append these two fields to the form, and normally, I would then add the form to the document, and submit it. Unfortunately, this didn't work right away. I noticed that form.submit() submitted the existing form in the HTML and not the new form that I had created using JavaScript. To fix this, I removed that form from the document body before adding the newly created form. This worked like a charm.

In the script process_post.php, I check the value of the id parameter to decide whether I have to create a new post or update an existing one. If a new post is being created, I show a form that allows me to enter the title, keywords, etc. If I have to update an existing one, I archive the previous version of the content before replacing it. The only extra functionality that I wrote, was a separate form to upload images. I know that CKEditor has add-ons that integrate uploading images in the WYSIWYG, but I like keeping control over where I put my images and how I name them. The standard image icon in CKEditor allows me to use the images I upload separately, and that's all I need.

I don't think I'm ever going back to a full-blown CMS system. Those things are getting way too bloated for my taste, and I hate having to update them every other week.

Topics: technology

Entreprenerd


Buy Bruno's book

Topics