Category: Website Development

Sassenach CMS 0.9 Released

Not a long post, this. I just wanted to alert people to the release of Sassenach CMS 0.9.

This is a first release and is not recommended for use on production websites right now as it's not quite polished. Treat it more as an evaluatory release.

For more information, please take a look at the Sassenach CMS website and Launchpad project pages.

Try it out and let me know what you think, and make sure you read the advice at the bottom before downloading. It's important! Also, please note that there is no documentation with this release, so feel free to ask me questions, and I'll do my best to answer them. I don't have a contact form for nothing, you know!

Sassenach CMS Is Almost Ready!

Having taken a little break from working on Sassenach CMS recently, I've cracked on with it again over the past few days since LUGRadio Live. I have been working on a few other projects recently, and so progress has stalled. However, having spent a couple of days working on different bits of the system, I think I'm happy for the world to see it. I'm labelling it an 0.9a (for alpha) release.

Basically, it is feature-complete, give or take a couple of exceptions. All of the files within the system work now, and, providing you don't do anything wrong, won't throw up a hissy-fit. However, if you do something wrong, they won't necessarily play ball, as my focus over the past couple of days has been finishing the system and not polishing it.

The project is registered at Launchpad, along with the code for the project which is there in its completeness. I using the system on a few websites, including this one, the BUSY website and the Sassenach CMS website, although at the time of writing, the Sassenach CMS website still diverts to another page while I prepare the website!

There are still a few things to do: I need to make a logo for the project, for intance. I need to review all the code, file by file, to make sure it is reasonably secure. I need to alter some of the backend appearnce, but this is just a cosmetic change.

There are, however, three things that are probably most important for me to get finished and polished. The first is to properly implement pluggable themes. These can be changed from the backend, but I want a more complete system where you just click on the theme you want and it works. It probably isn't a great deal of work, it just hasn't been finished quite yet. Secondly, I still need to move some of the code to functions, which I have started to do, but haven't finished quite yet. This is mainly for themes.

Finally, however, I need to write some documentation and create some screencasts, or something similar. This is the most important thing for me to work on.

There are a couple of other things I want to do, like finish my WordPress importer. I have now finished writing the installer. It isn't the prettiest thing you've ever seen, but I have tested it about 25 times now and it works. If the datbase has already been created and files have the correct write access, installation takes about 3 minutes. I think I can settle for that!

I expect I will post more about this during the week, but I think that's all for now!

Another Small Project

Following on from the small project I showed off last night, I thought I would draw a little attention to one more little project I've been working on - my recent links. I have, for a while now, had some recent links shown in my sidebar, but the sidebar only shows the most recent 5, and they have, until now, then faced oblivion. Not any more! I have a page devoted to showing them now.

I will, at some point soon, split them into monthly and yearly archives, although there's little point in doing this whilst there's only one month of such links to archive. I will also add an RSS feed and set up a monthly, automatic post containing that month's links. Aren't you all lucky!

Well, I am now off to the wonderful event that is LUGRadio Live 2008, which I'm sure I will post about later tonight or during the week!

Writing Functions In Sassenach CMS

I am currently carrying out a little more cleaning up of the Sassenach CMS codebase, starting with themes. At the moment, Sassenach CMS themes are fairly complicated and easy to break if you don't know what all the code does. This may seem an obvious point, but the average person designing a template doesn't necessarily want to deal with the entire codebase - they just want to style their website. In order to take away most of the complicated code, I have set about writing functions that call the code from elsewhere.

This, unfortunately, took much longer than I was expecting. In fact, it took 6 hours last night just to get one function working. It was, of course, all my own fault. So, before I explain the functions, two quick tips: firstly, if your function doesn't appear to work, make sure you've called it properly. Let's say we have the following function:

function my_new_function {

}

That's fine, as long as it is declared within PHP. However, when it comes to calling the function, don't make the mistake of doing this:

my_new_function; // This will not work!

Instead, make sure you call it like this:

my_new_function(); // This will work!

Basically, I forgot to include the parentheses when calling my function. Silly. Anyway, there was a further problem which manifested itselfwhen including other external files within my function. I was trying to do this:

include $file;

This wasn't working, however. So, I tried the actual file I wanted to include on this occasion:

 include 'file.php';

No problem. As far as I was concerned, $file == 'file.php', so it should all work. I couldn't work it out. It didn't make sense. It should work - but it doesn't. I checked my PHP and MySQL book, but it didn't give me an answer. I Googled for 3 hours, with no result. I checked the PHP website, Tizag, DevShed, everywhere else I could possibly think of, but no, nothing.

I chatted to someone on the phone about it. We decided Greek made more sense. Then, one of my housemates came back. We chatted for a bit. I rambled on about the problem for a few minutes. They listened politely, but I may as well have been talking Chinese.

Then, I went back to it. It still didn't work, so I copied a snippet of code from the PHP website. It worked. I adapted it. It still worked. I didn't understand at all. And then it hit me like a concrete block. It was obvious. Talke a look:

$file = "'functions/'.$function.'php'"; // Do you see the problem here?

include $file;

I am a muppet. I had double quotes that were completely unwarranted and broke the script. No amount of Googling would come up with that answer.

So, having exposed my blatant error to the world, hopefully I have saved others from the same mistake - and we can move on to Sassenach CMS functions. I didn't want the functions to all come from the database, because that puts unnecessary load on the database. Similarly, I didn't want to include every function at the top of every script when they weren't always needed. Thus, I have written a function that is designed to call other  functions as required. Here it is:

function get_sassenach_function($function) {

$sassenach_function = 'functions/'.$function.'.php';

include $sassenach_function;

}

 Thus, if you called the function like this:

 get_sassenach_function(links);

Then Sassenach CMS would, ultimately, run the script at 'functions/links.php', which then executes the code that no-one should really need to deal with.

However, there is a chance that people may want to use their own custom functions. What happens then? There is, of course, the option to hack the scripts, but I wouldn't advise this, especially as any upgrade would likely overwrite them again. Instead, we will have a directory within which people can place their own modified scripts and run them. So, that might look like this:

function get_sassenach_user_function($function) {

$sassenach_user_function = 'functions/user/'.$function.'.php';

include $sassenach_user_function;

}

 Thus, users can define their own functions and call those without having to worry about having their custom functions overwritten. More importantly, they can call their own custom functions easily.

There is, however, one other possibility. What if a particular theme wants to call its own functions? Well, the same kind of principle applies, except that the functions would be stored in a functions directory in that themes folder, and would use another slightly different call, yet to be written, which would be get_sassenach_theme_function($function). This will need to be a little different in design as it requires knowledge of which directory the theme is found in, but it will still wirk without too much trouble.

There is one more problem to overcome - what if you need to call a function more than once? This is actually quite easy to overcome, and it is done like so:

if (!function_exists('example_function')) {

function example_function() {

// The function is defined here

}

}

example_function(); ?>

So, each time the function is called, the top of the function file checks to see whether the function has been defined before. If it has, there is a problem - that functions can only be defined once. So, if the function has already been defined, it just calls the function. Otherwise, it defines the function and then calls it.

And so there you have it, a guide to functions in Sassenach CMS. What a fun post. Does anyone still have the will to live? If so, feel free to comment. Comments should now be working - if they're not, you should let me know!

Sassenach CMS - Another Update

I am slowly realising that I struggle to stick to my own, self-imposed deadlines. Originally, Sassenach CMS was set to launch on 1st June. That was missed, and 1st June turned into 1st July. Well, that was today, and that's been missed too. Let's aim for 1st August, maybe - although I will, helpfully, be away at the time.

Anyway, there are legitimate reasons for the delay, aside from the fact that I'm being a perfectionist and there's always more to do. I am, for a start, still working on an installer for the system. This is, I guess, fairly crucial, although you could just use phpmyadmin. I am also still working on a conversion script to import from WordPress, which is probably about 90% complete, but just needs a little tweaking.

I am also writing a password retrieval system which currently only half-works. I've written the first half of the script, but not the part that actually changes the password.

There are a few scripts that still need a small amount of tidying up, but there are two more parts that I am aiming to complete before Sassenach CMS is ready: templating and database execution of PHP.

The first, templating, will take a while and involves writing functions and designing a system to call those functions without downloading more than is needed at any one time. I have an idea for this, and if it works, I shall post about it further.

Secondly, I realised that sometimes it is useful to be able to execute PHP from a database. Unfortunately, TinyMCE strips PHP automatically, so I need to create an interesting way around this problem. Again, I have ideas, but I'll wait to see if they work before writing about them.

So, Sassenach CMS is almost there, but not quite. About the same as last month really! It might be ready by August - just don't expect the documentation!

Progress Is Good

Although I've done little on my little project today, I have spent three whole days working on it this week, rather than spending my time on my dissertation like I probably should have. Still, I managed a few significant things yesterday, so I thought I'd provide another short update.

My nice to-do list can now be updated without a problem, which has helped me keep track of things nicely. I was very excited on Tuesday to find the first two bugs in the code I'd written: there were two scripts which used the $_GET() function, and were meant to perform certain actions like delete things from the database when given certain variables in the url. I had, however, mistakenly allowed the script to delete as long as something was appended to the url, regardless of what this command was. Here's an example:

http://www.noelinho.org

That's the web address.

?action=delete&post=21

Those are the variables. When put together, we get this:

http://www.noelinho.org?action=delete&post=21

Assuming the action "delete" does what it says on the tin (and it does), then it will look in the database for post 21, and delete it. Unfortunately, my carelessness meant that it would have done the same if action was equal to "create", "modify", or even "" (blank). Still, it's on my to-do list to be fixed...

However, I have, much more excitedly, managed to implement that two things I thought would be hardest: RSS feeds and nice permalinks, using mod_rewrite. The RSS feeds were quite simple once I'd realised that certain html entities break XML, and then used the necessary PHP function to strip them from strings. It probably needs a little more work, but it's functional at the very least right now. I was even more satisfied to get mod_rewrite working. For some reason, I couldn't get it to work on my local server, but once I'd uploaded the scripts to this website, I managed to get them working. Thus, I can now start with an address such as:

http://www.noelinho.org?year=2008&month=01&title=noels-first-attempt

And I end up with:

http://www.noelinho.org/alpha/2008/01/noels-first-attempt/

Awesome! mod_rewrite is brilliant... but complicated. Like, nigh-on impossible. But not quite.

Another Noelinho CMS Update

I've been continuing to use whatever time I can to work on my little CMS project which I have mentioned before. Just over a month has passed since then, and I have managed to progress a little further, especially in the last week. Given that a few people have asked about it recently, I thought I'd post a little update.

I'm still only working on the back-end of the system at the moment - the front-end can be sorted out afterwards. The basic structure of thre back-end has remained the same, but I've decided to split many of the pages in the different sections into two or three pages. The idea of this is to make the whole thing easier for people to understand, and to make each page a master of its domain, so to speak, rather than to make it a lengthy complexion of 'if' statements for five different tasks. It makes working out bugs much easier too!

One significant change is in the way 'categories' are stored on the system. They were stored in a set' field on the 'posts' table, but I've now created a 'categories' table, and each category is a row on that table. It enables categories to have parent categories, but also means I can have one table for both link and post categories. There are problems with creating arrays from this at the moment, so I've decided I'll come back to it another time. I have kept my previous 'set' system just in case it doesn't work in the end, but I was more disappointed that I no longer had a use for my wonderful explode() code, which I did rather enjoy...

I have managed to adapt TinyMCE to fit better in the back-end now, but also to use a more complicated theme that didn't previously work. It still needs a little tweaking, but it would probably work fine just as it is at the moment.

Many of the other things I mentioned in my previous post have not yet been worked on, but there are other things which have progressed. Submitting new links now works well, as does submitting new categories for links, and distinguishing between post and link categories. Parent categories do not yet work, since that option hasn't yet been fully added to the database. The forms have all been nicely styled now too, making them both easier on the eye and clearer to use, as you can see from the image.

I haven't written any documentation yet (I expect this will be done last), but I have transferred my nice 'to-do' task list to the database. I originally developed this so that I could keep track of what I needed to be doing, but then realised it would actually be very useful for other people to keep track of all the things they wanted to do if they were using it too. Thus, the 'to-do' tab probably shows the most complete part of the software at the moment. It is split into three sections: 'implemented', 'in progress' and 'not yet started', with a form at the bottom for submitting tasks. In time, functionality will be added to alter task status and to delete tasks - but only completed ones. To delete uncompleted tasks, one will have to change their status to 'implemented', then delete them, so they can't delete them by mistake.

I Am An Idiot

I did something very silly today. I was working on my CMS Project today, but having problems. I was working away at a form for adding categories via the back-end of the system, but wasn't getting very far. The categories live in a SET column, which can take up to 64 variables, any number of which can be used for a particular post. If none are ticked, the post goes to a 'General' category. Anyway, updating a SET field takes some doing, so to edit it I need to go through the following process:

Nice and easy. The trouble was, it didn't do anything. It worked perfectly in phpMyAdmin, but not on my self-written script. I couldn't understand it. The code was perfect - I used echo() on my browser to make sure it was. I made sure all the slashes were correct. I used stripslahes(), addslashes(), and almost resorted to slashwrists(). But then it hit me.

I hadn't actually run the query on the database. I'd written all the PHP code to deal with the results the query would show up, but I hadn't actually run the query.

What a muppet I am. Please don't make the same mistake as me.

IMAP On Gmail

I've had a Gmail account for over three years now, and whilst Gmail is fantastic, especially in giving me about 6 Gigabytes of storage, one thing I've wished for a long time is that they would add support for IMAP. I used to use POP to access Gmail, it was frustrating when using multiple computers.

Well, I was fumbling around in my settings page today when I noticed that, since November, IMAP has been enabled on Gmail. That makes me happy!

I do, as an aside, also notice you can now use Google Apps on your website. One of the advantages of this is having a Gmail account with your website address in it, but with all the perks of Google's storage space. Handy, when you're strapped for storage space on your web hosting.

Noelinho CMS Update

I've been doing a little work on the Content Management System (CMS) I'm writing over the past couple of months, so I thought I should give a little update. I've made good progress this time, especially having solved my password troubles. Authentication has always been the stumbling block I've had in the past, but now that is successfully implemented, it's all dandy.

The main thing I've been looking to do is implement an inline text editor. I'm using TinyMCE, which is what a standard WordPress install uses. It's quite nice, although I've not managed to make it look the way I want it to, or add the features that I want in there, because I don't understand Javascript. I need to get my head around that, which may take a while. Javascript is a really stupid language if you ask me. I just don't get it - but then again, people say that about PHP too...

Anyway, TinyMCE is used to format posts, and I have managed to get it to write to the database, so it does work - I just need to make it fit better. Once items are in the database, they can be managed through PHP's $_GET system. I'm sure there's a newer, supposedly better way of doing this, but I've not come across it yet, so it'll stay like that for now. It's simple enough. I need to write a nice little help section too - something sadly left out of many systems. Why make people go to a forum if you can answer all the questions on the back-end of the system? I'm also in two minds on the options system to use: on the one hand, lots of people find it easier to hold certain options in the database. This is how WordPress works, but it's simpler to just hold them all in a file, and I prefer it that way too. It makes for quicker loading, too. One compromise could be to use a file that's written to from the database, but maybe that's just a waste of time...

I have, very helpfully, built in my own small to-do list on the back-end. This could, as the whole thing develops, be left as a little notes page for administrators to store thoughts and the like, but for now, it stores the things I need to take this project further forward: nice URLs and RSS feeds (nasty, both of them!), categories, pluggable themes and the all-important search facility. Hopefully I'll get some solid progress on this over the coming months, as there are a few people interested in using this if it turns out nicely, which it will!