Wordpress... Without Wordpress!

So in the time I've had after work last night and tonight I've started making the front end to wordpress but using my framework. There were a few motivations for this:

  • Wordpress has a POS template engine--or lack thereof. This is an arguable point, of course, because PHP is a template language.
  • I have no idea how many SQL queries wordpress + k2 perform on the main page, but I had a feeling I could do less.
  • I wanted more control over the front-facing side of my blog.

General

In the few hours that I have dedicated to this mini project, I have made quite a lot of progress! You can go see monitor my current progress if you would like to. Otherwise, I've made some general observations about wordpress.

First of all, I get the feeling that the wordpress creators have no idea what they are doing with databases. They need to settle on a single naming scheme for their database table columns. I can imagine that their excuse for the terrible column names was a result of backwards compatibility or some other meaningless argument. There's no excuse for this type of thing. If it were an issue of backward compatibility then when they were programming it then they should have stuck with the original naming scheme and left it at that. If it was a problem of different styles for its different developers then they need to learn how to coordinate their efforts.

It's total guess work about what column you want--especially for table primary keys and foreign keys! Some places have, for example: ID, cat_ID, comment_ID, post_id, category_id, etc. Last time I checked most (if not all) major databases supported ALTER syntax. And if they don't, then they probably support TEMPORARY tables in which case one can use as an intermediate for the data if a table's columns need to be renamed by dropping said table.

Second, their code is a total mess. I get the feeling that this is partly due to the need to be backward compatible to some point, hence their dependence on global variables.

Third, it's a wonder that everything works as well as it seems to. I'm astonished that its developers can maintain it.

Otherwise, since I haven't gone and looked too much at the wordpress internals, I thought I'd show how I solved a few simple problems, namely: archives list and post categories list.

Archives

In my framework I have made these great things called components. Components are controllers that can be accessed through templates using a simple XML tag. If you look at this blog, each box represents a component: menu, blogroll, archives, categories, etc.

My goal was that no component would execute more than one query, so getting the archives was interesting. You might think that getting the number of posts would be the tricky part, but it actually turns out to be how to get the months themselves. Here's the SQL query I came up with:

SELECT MONTH(post_date) as month_num, YEAR(post_date) AS year, COUNT(ID) AS num_posts 
FROM wp_posts 
WHERE post_status = 'publish' 
GROUP BY YEAR(post_date), MONTH(post_date) 
ORDER BY YEAR(post_date) DESC, MONTH(post_date) DESC

This is quite simple, I wouldn't be surprised if something similar is somewhere in wordpress.

Categories

Another requirement that I set for myself was not to do an extra query to get a posts categories. There was a rather simple solution to this problem. The categories component which lists out all of the categories would have to use the same result set as the categories that are listed under each post name. This means that the categories component does (ghast!) two queries and then every post listed on the front page takes information from those results and figures out which categories it belongs to (without any extra queries). Another requirement was that I not break any existing wordpress urls, that meant that the PHP category needed to have the /development/ parent category in its url.

You might be wondering why I needed two queries for the categories component. This was because I decided that to handle sub-categories, I would only allow for the display of one sub-level and I would use PHP to figure out which categories belonged to which parents. This was a rather simple thing to accomplish.

Regardless, I used a GROUP_CONCAT to get the category ids that a post belongs to along with the normal post data. Here's a super function I made for finding visible posts:

public function findAllVisible($page = 1, $limit = 10, array $filter = array()) {
	
	// build the base of the query		
	$query = new VK_SelectQuery("p.*, u.user_nicename AS author_name, u.ID as author_id", "wp_posts p, wp_users u", "p.post_author=u.ID");
	
	// visible
	$query->addWhere("p.post_status='publish'");
	
	// pagination
	$page = $page < = 1 ? 0 : $page-1;
	$query->addLimit($page * $limit) // start
	 	  ->addLimit($limit);        // offset
	
	// ordering
	$query->addOrderBy('p.ID', 'DESC');
	
	// default type filter
	if(!isset($filter['type'])) {
		$filter['type'] = 'post';
	}
	
	// filter the results further
	foreach($filter as $key => $val) {
		switch($key) {
			
			// by a specific cateogry
			case 'category':
				$query->addJoin("wp_post2cat pc", "pc.post_id=p.ID", 'INNER')
					  ->addWhere("pc.category_id=". (int)$val);
				break;
				
			// by a date
			case 'year':
			case 'month':
			case 'day':
				$query->addWhere(strtoupper($key) ."(p.post_date)=". (int)$val);
				break;
			
			// by an author
			case 'author':
				$query->addWhere("p.post_author=". (int)$val);
				break;
			
			// by type
			case 'type':
				$query->addWhere("p.post_type='{$val}'");
		}
	}
	
	// get the categoriy ids in a comma-separated form
	$query->addFrom("wp_post2cat ptc")
		  ->addSelect("GROUP_CONCAT(ptc.category_id SEPARATOR ',') AS category_ids")
		  ->addWhere("ptc.post_id=p.ID")
		  ->addGroupBy('p.ID');
	
	// get the posts
	return $this->findAllByQuery($query);
}

This fit nicely into PostsRecord class and lets me deal with details such as pagination easily.

Comments

That clearly shows off to what your framework is able to. Nice.

Wondering why you want to rebuilt Wordpress' Frontent, while you could create your own "rulish" application; blog.

What about OneLobby? ;o)

Well, for all the things I don't like about wordpress, there are a lot of things I do, for example: it has a great administration panel, it automatically deals with ping back and sending out pings, it supports tons of plugins (although with a new front end they won't be that useful) and it supports tons of themes (same thing).

On the whole, wordpress is an amazing product, I just don't think its developers are that amazing.

    by Peter Goodman on Jul 6, 2007 @ 8:57am

Hah, that's too funny. I just had a look at your Application Controller and was surprised how you implemented several ideas and routines.

Some are really equal to my code. Really cool. xD

Finally..

Someone else who is moaning about the absoloutly dire condition of wordpress code.

I have been making modifications to wordpress front and backend latly (for multi domain support) and i have to say, this is the biggest piece of botched code i've ever seen.

Its like wordpress was never intended for this level of use / size of project, and as a result, is a horrible mix of inline PHP, HTML, Ajax, XML and JavaScript.. worse than this, wordpress have t-shirts..etc saying 'Code is Poety'.

The guy who built wordpress, Matthew Mullenweg basically is a dreamweaver loved, and used it to build wordpress thanks to its excellent PHP Support... no wonder the things crap.

http://ma.tt/2008/02/wither-dreamweaver/

Chloe

You may have a point with the backward computability. However, I have spent some time recently trying to do a few basic things with WordPress, but it is nigh on impossible because of the absolutely terrible structure to the code. Pretty much everything you do goes though multiple files in an illogical manner.

An average page on WordPress will execute somwhere in the region of 100 - 300 PHP functions! and around 30 MySQL queries. And thats not all, some so-called PHP files are laced with HTML, JS, RSS and XML. Any decent programmer should know that anyone who is producing such files is an absolute programming baby.

Good look with your WP re-build. I'm sure it will rip it to pieces.

Add a Comment