Duindain
Article Creator and Editor
Background
A few weeks ago I was writing a tool to fetch movie details from an online movie database and create a sqlite database based on only your own movie collection. While I was working on it I found a average tutorial on creating console progress bars and when I had finished I decided it would be a good idea to post my own code as an example to others on how to make it a real world use application. You can view that article here.
I used a web design tool to quickly mock up a blog type post on the article and wrote it up. Once I finished i thought there were a few other things I'd like to post about but the web design tool didn't let me create a similar looking article with the same theme without jumping through hoops. The main problem when I viewed the source code and it was an absolute mess of junk redoing styles multiple times on single elements just to enlarge text or change colors and the data was stuck into the style of the site so I couldn't edit it very efficiently.
Idea
I thought I might try making my own article renderer which separated content from presentation. Mostly I wanted to be able to quickly write and publish an article without having to perform multiple processes and submits that would allow me to create rich content and get it up and running fast with the ability to re-edit once submitted.
Implementation
I wrote the majority in PHP storing the article content in a MySQL database. Articles were accessed by passing URL arguments to the PHP script. It worked quite well the articles were rendered correctly you could change to the next article by changing the id value passed in the URL.
The pages supported complex HTML within the content including multiple images, rich formatting of text, JavaScript, Jquery and I added native support for SyntaxHighlighter as the first article was a code based one so I needed something to nicely format and allow copy / paste of the code examples.
I spent a week in the end polishing the renderer, getting Syntax highlighter working reliably without pinning it down to just a few languages, getting the style from my original web tool developed blog ported across correctly to the new dynamic version.
Provisions
This was a success for this individual article that I had pre-created, I was able to cut out the content from the styling and paste it into the MySQL database and eventually render it in a comparable quality. When I tried creating a new article I had a large amount of trouble getting the content to match the display I was after, everything I tried either did not preserve line breaks and formatting when output or did added non html renderable additives to the text.
Editor
Eventually I thought the trouble I was having warranted a proper client application to allow me to create these articles easier that just copy and pasting them into the MySQL database.
I started work building an editor. I used the following API's and tools to get the editor running;
- CKEditor for the rich text editor field
- PHP and Jquery to populate a list of currently existing articles owned by the author
- Ajax to send requests to the PHP backend for requests
CKEditor was perfect as a rich text editor it allowed me to maintain formatting add complex html and rich content which was preserved in MySQL and when output from the render. It was easy to incorporate into my code and It's API allowed me to continue using Ajax to update the content.
I added a new table in the database for user access and altered the original article table to use the new field from the user table as an author and threw in a quick login script that is proffered the the user on first visit to the editor. I have not enabled registration ability yet and the authors are manually added by me as I am not convinced on releasing the ability to publish sites to everyone yet.
I wanted the editor to interact seamlessly with the backend so there is just a single PHP page with Ajax scripts for all the updates, deletes, submits, uploads and edits for articles. The page is never reloaded for any action.
One of the most troublesome problems was uploading the header image to the site. To do this with Ajax queries and not full page submits is a non supported ability for Ajax. I ended up having to use Jquery-File-Upload by Blueimp since it was the only API that I could find that had a mostly working demo with example files that actually did what was advertised.
I decided to add a "Go Live" feature to the editor allowing a author to control when their article went live as previously the articles were always visible when not complete, this was an easy function as I just had to add the field in the article table and change the select query for viewing articles to make sure that field was true thereby ignoring all non live articles in one sweep.
I ran into several limitations of IE while creating the style of the editor site, not supporting curved corners properly, not supporting callbacks from the upload, several custom CSS "fixes" to make IE render elements correctly and various other peccadillos along the way. Due to this I decided to put a warning out when a visitor uses IE to access the site that they are operating an inferior browser and should upgrade to a decent one Chrome or Firefox for example.
Polishing
In the end I had the editor and render working side by side with no major issues however I wasn't happy with several features I had built in;
- Security wise leaving the renderer accessible to everyone seemed like it could end badly
- Single point of failure for rendering all articles
- Meta data allowing the articles is created but as the pages were created on demand, search spiders wouldn't have been able to see that data to index it
- I was worried there might be performance issues rendering many articles simultaneously when they all had to go to the same source page
- I didn't want users hyper linking to a rendered document passing values to it as this seemed unstable in the long term
These reasons seemed significant enough to me to justify changing the solution I had found in favor of something more multi-user friendly that could allow search spiders to index the results. I decided to change the renderer from echoing output to the client to outputting to a local file on the server. When the page is first accessed from the renderer it now will output to the local file. If it already exists it redirects to the local file instead.
This worked but there was a problem left. How would I update the saved page with new content if an edit was made. To address this I needed a way of indicating that a page required an update. The first step was to add a new field to the database indicating when an update needed to occur.
This was set by the Article Editor when a change was made. Now I was left with another issue, how to trigger this update from a html page? I couldn't think of an easy solution and I didn't want to compound any security issues by having more Ajax to check for updates, I changed the output script in the renderer to output PHP pages instead of html.
I then added a short snippet that is echoed out to every generated page when first created that checks the database to see if an update is necessary from the new field. If it is then it removes the current page then redirects the client to the renderer. The render will see that the page no longer exists and that is needs an update so it will then regenerate the page and reset the needs update field to false. It then redirects the client back towards the saved page. This action takes almost no time on the current web server and is effectively unnoticeable.
This solved my issues as there is now a static page to link to on external links, it allows authors to generate articles and update them when necessary and auto updates the source on the next visit of any client only when necessary. It allows search spiders to find the meta data of the articles and index them and it minimizes security issues by keeping all database details on the PHP side and limiting the communication between client and server.
One feature I had been missing up till now was the ability to preview a page from the editor while writing it. This is a feature I often use when posting responses and queries on forums so I felt it was definitely necessary. I added another command line argument to the renderer to accept directives on whether to cache an article or not. I added a new Preview button to the editor which sends a Jquery Window Ajax request targeted to the renderer sending it the preview command. It opens a new window with the Article available for reviewing, this option is only available once an article has been saved to the database.
Conclusion
Though there are tools out there that do the same job as what I have accomplished here like Drupal, WordPress, Joomla and others, these tools are slanted towards a very different user base generally not as technically orientated. Usually not supporting the full range of JavaScript and Jquery functions within the content.
I would very much like to gain the pre-made customizations, plugins and themes from these tools, I believe my solution is faster to post an Article easier to customize rich content and much better suited to my use case which is short to medium length articles that can update themselves when necessary with native support for the latest Jquery and SyntaxHighlighter addons with inbuilt JavaScript support.
I believe the management of these tools to be quite top heavy compared to my tool which has a single page to edit, delete, modify and create new articles with minimum effort.
Future Work
Once I am happy with my renderer and editor which will be very soon I will revisit allowing registration to the system to allow people to sign up and begin posting their own articles.
I need to add new styles to the articles. This is already supported but I haven't yet taken the time to generate others.