I've played around with website baker for around two weeks now. Generally I really like it, especially the admin interface is nice and clean. Naturally there are a few things that could (in my opinion) use improvement:
- No support for caching (pages always generated on the fly)
- I don't like the pages being files (with just id reference and some includes)
These are not critical things, but just something I'm missing. Here are examples of how I modified WebsiteBaker to support caching and get rid of the pages/ -structure.
First off, I used mod_rewrite to parse the requests coming from the clients. This is easy to set up if you've got mod_rewrite installed. Just add the following lines to your .htaccess in the document root (you can also place them to apache conf files):
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !/templates
RewriteRule .+ php/display.php [L]
This will tell apache to send all incoming requests to php/display.php. Exceptions (for images, styles, etc.) can be set using RewriteCond. To check whether mod_rewrite is working ok, just echo "hello world" in your display.php. If it works, then let's move on.
The wb pages-table contains a field called link. This field can be used to dig out the id of the page according to the request. The link is without suffix, so we first need to get rid of it in our display.php:
$request = explode(".",$_SERVER[REQUEST_URI]);
$request = $request[0];
Once we have it in correct format, we can get the page_id from the database by comparing the request and the link field:
// require config and database class
require("../config.php");
require(WB_PATH.'/framework/class.database.php');
// setup database object
$database = new database(DB_URL);
// get page id from db
$query = "SELECT page_id FROM pages WHERE link='$request' LIMIT 1";
$page_id = $database->get_one($query);
// move on
require(WB_PATH."/index.php");
So now you have it. Basically the files in the pages -directory are not needed any more. You can still keep them, no problem. It could still use improvements like sending a 404 if there's no matching link for request, etc.
The reason I wanted everything to be parsed through display.php was that then I could easily set up caching using PEAR::Cache_Lite. Cache_Lite simply saves a copy of the data sent to the browser as a file. The copy can be set to be valid for a certain time (say an hour). Any requests coming in within the time limit get the saved copy instead of getting documents generated from the database. Cache_Lite has good documentation online, so I'll just copy the display.php that I used to enable caching:
$request = explode(".",$_SERVER[REQUEST_URI]);
$request = $request[0];
// include cache class and set her up
require_once('Cache/Lite/Output.php');
$options = array(
// set save dir (must be writable by webserver)
'cacheDir' => '/path/to/cache/files/',
// set cache life time (in seconds)
'lifeTime' => 3600
);
$cache = new Cache_Lite_Output($options);
// if page (identified by $request) does not exist in cache....
if (!($cache->start($request))) {
// require config and database class
require("../config.php");
require(WB_PATH.'/framework/class.database.php');
// setup database object
$database = new database(DB_URL);
// get page id from db
$query = "SELECT page_id FROM pages WHERE link='$request' LIMIT 1";
$page_id = $database->get_one($query);
// move on
require(WB_PATH."/index.php");
$cache->end();
}
The only problem left is the fact that updates via the admin interface don't empty the cache. The following method is crude, but works. I modified class.admin.php:
function print_footer() {
// cache hack, janit
include(WB_PATH."/framework/cache_clean.php");
This bit includes the cache_clean.php on every page of the admin interface:
if (strpos($_SERVER[REQUEST_URI],'/pages/')){
require_once "Cache/Lite.php";
$options = array('cacheDir' => '/path/to/cache/files/');
$cache = new Cache_Lite($options);
$cache->clean();
}
Now the cache is being cleaned constantly while you're moving around in the pages-section of the admin interface. That's it. Now you're running a cached WebsiteBaker that's bypassing the pages-directory.
Finally some benchmarks from Siege. I ran a single url for 60 seconds with no cache and then with 20 second cache:
NO CACHE
Lifting the server siege...done.
Transactions: 610 hits
Availability: 100.00 %
Elapsed time: 60.19 secs
Data transferred: 7271200 bytes
Response time: 0.96 secs
Transaction rate: 10.13 trans/sec
Throughput: 120804.12 bytes/sec
Concurrency: 9.76
Successful transactions: 610
Failed transactions: 0
Longest transaction: 14.20
Shortest transaction: 0.07
-------------------------------------------------
20 SECOND CACHE
Lifting the server siege...|done.
Transactions: 1624 hits
Availability: 100.00 %
Elapsed time: 60.14 secs
Data transferred: 19358080 bytes
Response time: 0.03 secs
Transaction rate: 27.00 trans/sec
Throughput: 321883.61 bytes/sec
Concurrency: 0.79
Successful transactions: 1624
Failed transactions: 0
Longest transaction: 1.00
Shortest transaction: 0.01
I hope this is of use for somebody
