Restoring an InnoDB database from raw files (on Ubuntu)

Recently I had to replace my computer’s hard drive as the old one was getting close to dying. In the chaos that comes from copying files from one drive to another, I completely forgot to  back up the databases on the old hard drive. I was still able to access the raw files, however, and after some hair-pulling and a lot of googling, I was able to restore the tables I needed like so:

  1. On the old hard drive, I navigated to the /var/lib/mysql folder
  2. I copied the database folder I needed to the new hard drive (this contains a bunch of  files ending in .frm; the names should be those of the tables on that database). For convenience I copied them to the Desktop.
  3. I then copied the ibdata1, ib_logfile0, and ib_logfile1 files to the Desktop
  4. On the command line I stopped mySQL – sudo service mysql stop
  5. I backed up the ibdata1, ib_logfile0, and ib_logfile1 files by appending -bak to them. To do this (since you can’t exactly browse the /var/lib/mysql  folder using cd) I entered sudo mv /var/lib/mysql/<filename> /var/lib/mysql/<filename>-bak (replacing <filename> with the respective file names mentioned above)
  6. I then copied the 3 ib files from the Desktop to the /var/lib/mysql folder – sudo cp <filename> /var/lib/mysql/<filename>
  7. Make sure all 3 of those  files are owned by mysql. If not – sudo chown mysql:mysql /var/lib/mysql/<filename>
  8. Copy the database folder – sudo cp -R <database> /var/lib/mysql/<database>  (where <database> is the database name)
  9. Give mysql ownership – sudo chown -R mysql:mysql /var/lib/mysql/<database>
  10. Restart mysql – sudo service mysql start
  11. Check phpMyAdmin/Adminer/Database tool of choice to ensure everything shows up properly!

Hopefully this helps someone else!

Comparing Laravel, CodeIgniter, & CakePHP

Today I received a comment on my Laravel Auto-Generating Named Routes post that I felt deserved its own post.

Matthew Schenker wrote I see you’ve worked with CakePHP and CodeIgniter, and now you’re mentioning Laravel. I’ve been happily using CodeIgniter for a while now, but lately I see a lot of people mentioning (and loving) Laravel. I’m not looking for one of those “which is best” answers. Long ago, I learned that this is not a good way to look at various frameworks. But I’m curious — what are your general impressions when comparing these three frameworks?

CakePHP, CodeIgniter, and Laravel are all great frameworks in their own rights. They each have their pros and cons which I will cover here. Bear in mind that these are my opinions and forming your own by messing a bit with them is always the best policy. And as mentioned in Matthew’s comment, this is not an “OMG FRAMEWORK X IS TEH BESTEST!!!1!” post.

Cake, if I recall correctly, was one of the first PHP frameworks around back when spaghetti code was standard. The idea behind Cake was to make developing applications fast (ie, “convention over configuration”) by cutting down on how much code the developer needed to write. Less time working means more time making money.


  • Built-in ORM which I’ve always really enjoyed. I really like how the results are in $post[‘Post’][‘field’] format. Building queries is really simple and you can fetch (for example) a blog post and all of its comments in one or two lines of code.
  • Reverse routing. This makes maintaining links in an application so much easier. This means if you change a controller’s name at some point, instead of search/replacing 200 instances of “admin/foo” with the new “admin/bar” (and hoping you didn’t miss one) you simply update the route in one place. Any links using the reverse route array will automatically point to the right spot at runtime.
  • Big community. Because Cake had been around so long you can find the answer for pretty much any question you come up with. If you can’t? They have their own website where you can submit questions, as well as (I believe) a mailing list.
  • Plugins. This makes re-using code super simple and help keep the app folder clean (if, for example, you are distributing an app that uses modules).


  • Incredibly slow. Recent versions of Cake (2.2.x as of this post) are much faster and more efficient than previous versions, but  it is still one of the slowest frameworks. I am personally not sure how well it holds up when an app of it gets slammed with tons of hits. I am aware that Mozilla’s plugin site runs on an (old) version of Cake, as does Cake’s own bakery and Q&A sites, which all seem to run fine. I suspect it’s a balance between caching and server fine-tuning.
  • TONS of lines of code. Some developers don’t care what’s going on under the hood; I like to be able to quickly find out how/why something works the way it does. The code is well documented but there’s just so much of it it can be overwhelming.
  • Occasionally, you need to use code to reign in just how much it does. For example, my first step is to open my AppModel and set $recursive = -1 and adding Containable to Behaviors to prevent it from auto-grabbing related models and letting me tell it what I need.
  • Autoloading can be awkward. In recent versions of Cake they’ve introduced lazy loading in the form of  App::uses. Then, if you need to have access to (for example) the Model class, you do something like App::users(‘Model’, ‘Data/Model’) at the top of the file. This is, IMO, clumsy and no better than doing a require CORE_PATH.’Data/Model/Model.php’;

Conclusion: Personally, I use Cake if I need to put together a dynamic site quickly that I don’t foresee getting a lot of hits (like for a local restaurant, for example).

I’ve mentioned on here before that CI was the first framework I ever used and helped me finally understand the concept of OO programming. It’s certainly popular, and has been around a similar amount of time as Cake.


  • Super easy to set up and use. This makes the entry level for a newer PHP developer much lower.
  • Extremely well-documented, with examples in a lot of places to illustrate usage.
  • Extremely fast.
  • Huge community. As with Cake, since CI has been around so long you can almost always find your answer via Google, CI forums, or their IRC channel. This also means there’s lots of code contribution to help get things done (like Paypal libraries, etc)
  • Sparks, the “hub” where CI packages go to hang out and be used.


  • No modular separation by default. This is a big deal for me as I prefer keeping my code as separated as possible. There is Modular Extensions, which does the job, but I’ve never been 100% satisfied with it.
  • Since 2.x broke CI has been 5.1.6+ for its minimum PHP version, but the whole $this->library, procedural function helpers, and extending a class by prefixing MY_ in front of it way of doing things just doesn’t work well for me. Perhaps this will change in 3.0? *shrugs*
  • I personally have to extend way too many core files to get CI working the way I like it. The more you modify the core, the more you have to maintain later. I’d rather be coding something productive.

Conclusion: CodeIgniter is a fantastic framework for getting the hang of PHP and OO coding and for knocking a small site together fairly quickly with low overhead.

Laravel is still in its early days compared to the “grandpas” of the framework world (I believe it was first introduced in 2011), but it has already gathered quite a following.


  • Modularity is built in via “bundles”, making it really easy to drop in/reuse code across application
  • Eloquent ORM is a simple, super fast ORM that makes working with database relations easy
  • Very configurable and extendable. I can set up apps with the folder structure the way I like it and how it works best for me.
  • Blade template engine. Very fast (compiles to PHP then caches the results) and very extendable. So easy to add new features without hacking the core.
  • Artisan (CLI). Before I started using Laravel I had zero use for CLI tools like migrations and tasks. It’s so easy to create both of those things with Artisan that I can’t believe I waited so long to try it out!
  • Reverse routing!
  • Excellent documentation.


  • It’s still quite new which can mean some instability with the code. However, since 3.x’s release (and certainly since 3.2.x’s, the most current as of this post) this has slowed down quite a bit.
  • Laravel’s core files are all within (at least) the Laravel namespace and not all of the files in core use a namespace slash ( a \ ) in front of a call to another core file, which makes extending some classes a bit trickier. This is not a huge issue and one not every developer will need to worry about.
  • Routing can feel a little odd sometimes. In my dynamic controller routing post I showed the workaround I used to dynamically route to an add function in any controller. I have not dug deep enough into the semantics of Laravel’s routing methods to understand why such a workaround is necessary but it does add another layer of complexity, IMO.
  • Because of its newness the options for finding answers are still limited in comparison to CakePHP and CodeIgniter. However, the forums and IRC seem to be quite active with helpful people, so usually the answer is findable.

Conclusion: Laravel is currently my framework of choice. Its coding style meshes the best with my own which makes developing much quicker for me.

So there you have it! A personal comparison of 3 big players in the PHP framework world. As always, the best framework for you is the one that you code best in. The “Cons” foreach 😉 framework are my personal beefs with each of them and should be taken with a grain of salt. The best advice I can give is to try them each on for size and see which you like best.

UPDATED (Laravel) Auto Generate Named Routes For Easy Reverse Routing

UPDATED: It occured to me that having the route names match the controller name might not lend itself well to preventing the need to update multiple places in the event of a controller’s name changing. I have updated this post with a better method to tackle that.

What *Is* Reverse Routing?
Reverse routing is an awesome feature. In Laravel (as well as other frameworks) when you create a route you can also define a name for it. Then, when you need to generate a link in your app, instead of doing your standard

<a href="/blah/bler/blo">Link</a>

You can do this:

<a href="<?php echo URL::to_route('some_route', array('bler', 'blo')); ?>">Link</a>

The difference, you ask? Let’s say later you decide to rename the Blah controller to Clover. You’d have to go through your entire app and replace any links starting with “blah” with “clover”.

With reverse routing, you’d make exactly one replacement: in the routes.php file. Any links in your app using the second example will automatically go to the clover controller. Yay!

So How Do I Do The Magic?

As you can tell, I very much like using reverse routing. However, I realized that Laravel does not automatically generate names for the routes created by Route/r::controller (which is not a critical flaw; not everyone has the need for it, and that’s fine). After a bit of digging and head-scratching I came up with a fairly easy way to have it do the work of naming all routes for me.

NOTE: This requires manually setting your controller names instead of using Controller::detect() (probably not a bad idea anyway since it’s less file lookups for Laravel to do)

1. Open routes.php and list the controllers for the bundle. If you want to specify a name, do a key => val pair. Example:
// This will set the admin/home controller as a route named foo
'foo' => 'admin.home',
// This will be a route called users, since we did not set a name

2. Create 2 files in your application folder. I placed mine in application/libraries. route.php and router.php.

3. Open up router.php and put the following into it:


class Router extends Laravel\Routing\Router {

* Register a controller with the router.
* @param string|array $controller
* @param string|array $defaults
* @param bool $https
* @return void
public static function controller($controllers, $defaults = 'index', $https = null)
foreach ((array) $controllers as $as => $identifier)
list($bundle, $controller) = Bundle::parse($identifier);

// First we need to replace the dots with slashes in thte controller name
// so that it is in directory format. The dots allow the developer to use
// a cleaner syntax when specifying the controller. We will also grab the
// root URI for the controller's bundle.

///// Here is where the named route will be set. If the $as variable is numeric,
//// we will use the controller name
(is_numeric($as)) and $as = $controller;
$controller = str_replace('.', '/', $controller);
$root = Bundle::option($bundle, 'handles');

// If the controller is a "home" controller, we'll need to also build a
// index method route for the controller. We'll remove "home" from the
// route root and setup a route to point to the index method.
if (ends_with($controller, 'home'))
static::root($identifier, $controller, $root);

// The number of method arguments allowed for a controller is set by a
// "segments" constant on this class which allows for the developer to
// increase or decrease the limit on method arguments.
$wildcards = static::repeat('(:any?)', static::$segments);

// Once we have the path and root URI we can build a simple route for
// the controller that should handle a conventional controller route
// setup of controller/method/segment/segment, etc.
$pattern = trim("{$root}/{$controller}/{$wildcards}", '/');

// Finally we can build the "uses" clause and the attributes for the
// controller route and register it with the router with a wildcard
// method so it is available on every request method.
$uses = "{$identifier}@(:1)";
///// Just adding the as variable to the compact statement so it'll get set upon register
$attributes = compact('uses', 'defaults', 'https', 'as');

static::register('*', $pattern, $attributes);


Here we are basically adding a couple of lines so the named route (defined by the ‘as’ attribute) will be created for us when Laravel is detecting controllers & generating routes.

4. Open up your route.php file and add the following:


class Route extends Laravel\Routing\Route {
* Register a controller with the router.
* @param string|array $controllers
* @param string|array $defaults
* @return void
public static function controller($controllers, $defaults = 'index')
Router::controller($controllers, $defaults);

* Register a secure controller with the router.
* @param string|array $controllers
* @param string|array $defaults
* @return void
public static function secure_controller($controllers, $defaults = 'index')
Router::controller($controllers, $defaults, true);

The reason we need to extend the route.php file as well is that the default file (found in laravel/routing/route.php) points to laraveroutingrouter, which means our custom router class would never get used. So, we simply override the controller functions and add the handy backslash in front of the Router call so it will look for our router file.

5. Open up application/config/application.php and comment out Route and Router in the aliases section.

You should now be have auto-generated named routes. The best part is that any custom route names you define will not be overridden by this method.

(Laravel) Quick Tip: Dynamically Route a Controller

When I’m working on a controller, I usually will combine my add/edit methods to help keep my controllers lean and mean. In the other frameworks I used this was generally as easy as adding a route like so

// CodeIgniter
$config['([a-z\_]+)/add'] = '$1/edit';
// Kohana
Route::set('manage', '<controller>/add', array(
'controller' => '[a-z0-9\_]+'
->defaults(array('action' => 'edit'));
// CakePHP
Router::connect('/:controller/add', array('action' => 'edit'));

However, in working with Laravel it just wasn’t that easy, probably because Laravel expects all controllers to be defined so it can do a super-quick search for them at runtime. I came up with a (hacky) solution that modified the core controller class (while I really enjoy working with Laravel the fact is its core just isn’t terribly extensible). I really hate modifying core classes.

And then – the lightbulb went on! I remembered that a) I can use anonymous functions for routing and b) Controller::call can be used anywhere.

NOTE: For now this only appears to work in subfolder controllers. It seems (from examining the generated route list) that any route that *starts* with a wildcard (eg, (:any)) will be moved to the bottom of the list. For me, this wasn’t a big deal; my add/edit classes are almost always in admin folders anyway.

Route::any('admin/(:any)/add/(:any?)', function($controller,$params=null) {
return Controller::call('admin.'.$controller.'@edit', (array) $params);

There you have it! 🙂

Quick Tip: Laravel 3.2.0 Auth Driver

I am upgrading a current project to Laravel 3.2 and had a bit of confusion with the (newly implemented) Auth drivers. I’m sure a lot of developers are able to use the Auth class as-is, but because I need some custom stuff returned when logging in/retrieving a user, I needed to figure out how to re-implement this logic.

Previously, the auth.php config file held the logic for logging in and retrieiving a user. Now, that logic has been moved to drivers (which, really, makes much more sense, but that’s just my opinion). With some help from the (awesome) forums, I was able to quickly port my code over.

1. Create a file in /libraries. For example purposes, we’ll call ours nerdy.php
2. The skeleton class for an Auth driver should look like this:

class Nerdy extends \Laravel\Auth\Drivers\Driver {

public function retrieve($id)

public function attempt($arguments=array())

2. Add your logic to the 2 methods.
3. Open up your application/start.php file and add the following:
// Of course, you would change the class name and path to
// the actual name & path for your app.
'Nerdy' => __DIR__.'/libraries/nerdy.php

Auth::extend('nerdy', function() {
// Again, the class name should be the name you chose
return new Nerdy;

4. Finally, open your applicatin/auth.php file and change the driver value to (in this example) nerdy and save.

Not so bad once you know what to do! 🙂


Extending CodeIgniter’s Database Forge Class

UPDATED 2/13: Added License (MIT) Info to code
UPDATED 1/13: Changed ‘required’ ‘required_once’ to avoid errors of redeclaring CI_DBforge

I am working on a project in CodeIgniter that requires use of the database forge class to create/modify/delete database tables. Because the project makes use of database transactions, creating tables with the MYISAM engine was not going to work. So I was faced with two choices: Make all the database creation, etc run by manual queries such as
CREATE TABLE `blah`...
or extend the dbforge class. After some tinkering about I finally managed to successfully do this. Here’s how:
(Note: I am using CI 2. This also assumes you are somewhat familiar with extending CI classes)

  1. Create a MY_Loader.php file in application/core (or open it if you already have one).
  2. If you had to create the MY_Loader file, paste the following:
    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class MY_Loader extends CI_Loader {
  3. Paste the following in your MY_Loader file:

    * Extend the Database Forge Class
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    function dbforge()
    if ( ! class_exists('CI_DB'))

    $CI =& get_instance();
    $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';

    require_once BASEPATH.'database/DB_forge'.EXT;
    require_once BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;

    if( file_exists(APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT) ) {
    require_once APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;
    $class = 'DB_'.$CI->db->dbdriver.'_forge';

    $CI->dbforge = new $class();

    This basically adds the code to find/include the extended class, and instantiate it

  4. Next you need to create some folders in your application directory. First, create the folder database. Then, within the database folder, you’ll need to create a drivers folder. Within the drivers folder you’ll need to create a folder for the database type (mysql, mssql, etc) you are using. Since I am using MySQL, I created a mysql folder. My folder structure, then, looked like this:

  5. In the driver folder you created (in my case, the mysql folder), create a file in the format _forge.php. In my case I created mysql_forge.php.
  6. Create your extended class:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class DB_mysql_forge extends CI_DB_mysql_forge {
  7. Have fun extending the functions! To get my tables to specifically create with the InnoDB engine I used the following code:

    * Modify _create_table to use InnoDB
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
    $sql = parent::_create_table($table, $fields, $primary_keys, $keys, $if_not_exists);

    $sql = rtrim($sql, ';');
    /* Should note here that I have a custom config file with the key/value pair to hold the
    default database engine to use */
    return $sql.' ENGINE='.config_item('database_engine').';';

I tried simply extending the dbforge class but since all the magic happens in the driver classes it was necessary to extend the driver and modify the functions there. Also, I know there are ways to set the mysql server to default to InnoDB creation but since this project may be sold/released at some point it is easier to modify the CodeIgniter files than to try and provide instructions for something most people wouldn’t be able to or know how to do.

Bespin Theme for Geany IDE

I love the Bespin theme that can be found for Textmate, Notepad++, and Gedit. Recently I started using the Geany IDE ( as it’s a lot lighter than Eclipse/Netbeans/etc.

I spent the better part of an afternoon using the Online Theme Editor found at ( to recreate (to the best of my abilities) this theme which can now be found at Please note that I only changed a few of the file definition files as that was all I needed to work with. If you are using a language other than HTML, PHP, and Javascript you’ll have to visit the theme editor I linked to above and make the changes there.


A Follow-Up on Kohana 3 & CodeIgniter 2 – The Flip Side

The other day I wrote about my experiences/opinions with Kohana 3 and CodeIgniter 2. I’ve received feedback from both sides of the debate, and want to share some follow up thoughts and some of (IMO) CI2’s downsides.

Shadowhand commented:

…This is typical of pretty much all programming tools. For example, look at Python right now… they have been on the 2.x series for a long time and 3.x is not backward compatible.

I will be the first to admit that Kohana has had development instability in the past, but 3.x is rock solid and has a real release process in place. Please help us by judging 3.x separately from other versions.

I should say that my basis for opinion on the “instability” of Kohana has been based on its rewrite between versions 2 and 3, and the rapidity in which those major versions came out. IIRC, the 2.3 series (when I first started dabbling with it) was released in the early-mid 2008, and the 3.0.x series started to become available in mid-late 2009. If I had written an app for release with 2.3 in late 2008 and then been faced with a rewrite a year later that would’ve cost quite a bit just in man hours just to learn the framework (again) and figure out a semi-painless way to migrate my existing code to work with a new code base. Not to mention rewriting docs for my users, and so on.

To be completely fair, CodeIgniter 2 has a lot of its own shortcomings. I previously mentioned the procedural helpers, and the fair bit of hacking required (for me) to get it working the way I want (usually involving modules and autoloading, which yes, are a core part of Kohana). Another thing that irks me with CI is how the config items are lumped into one huge array which can make it very difficult at times to ascertain which config file I got a variable from, not to mention the possibility of item name collisions. Usually to get around this I would simply prefix my custom config files with file_configitemname, but that’s not entirely helpful for the core config files.

And please, PLEASE don’t get me started on using “eval()” in the database class. I know it’s a bit of a workaround…and a lot of times I use my own class or Doctrine, but even so..

Stewart commented

…I do have a problem with how they went about it (they should of made it clear KO2 had no future, rather than stringing people on and a new version number doesn’t really make it clear it is really a new framework.

This sums up my feelings pretty well. From what I’ve been able to ascertain (looking through commits on github and such), the API has remained fundamentally the same in the latest series.

And perhaps, for me, that was it. I just want to know there is fundamental stability within the framework itself, without the worry that my code will have to be completely reworked every 12-16 months.

FWIW I do find developing with Kohana quite easy and fun, and if the recent fundamental stability holds out I may be singing a different tune.

I should also take a moment to thank both EllisLab and the Kohana dev team for putting the countless hours into developing these frameworks so I don’t have to! 🙂

Kohana 3 & CodeIgniter 2

For the last month or so I’ve been developing an app side-by-side with Kohana 3 and CodeIgniter 2 to see which framework fits my programming style better. Nothing terribly fancy; just a simple CMS.

I’ve been using frameworks to develop since 2006, back around CI 1.5.x. The differences between CI 1.7.x (the latest version as of this post) and CI 2.0 are negligible. My biggest nitpick comes with the helpers. I’m lazy and I’m also somewhat speed-conscious, which means I either need to autoload all the helpers my app needs in the autoload.php file (or early in my app) to appease my laziness, or load them as needed to appease my speed-consciousness. It irritates me that they’re basically files holding groups of procedural functions and if I want to access the CI super global I have to instantiate it in every function.

I started dabbling with Kohana a couple of years ago, in the 2.3.x era. I really loved their use of static functions (I’d only had basic OOP experience at the point), but I just never felt comfortable with the way things changed so much between versions. Last year when v3 was announced I had a look through the code and said “forget it”. But eventually I became curious again and started learning it to see how easy/hard it was to develop with it. I personally did not have a lot of trouble learning Kohana 3, between the user guide and the unofficial wiki. Perhaps my biggest stumbling block came with the Database module, which was a complete change from any of the v2.x database classes.

I really didn’t find either framework harder than the other to code for. I was able to more or less figure out how to do what I wanted to do in both. Yes, Kohana’s docs suck and CI’s are much better. For me it wasn’t much of an issue.

In the end it comes down to framework stability for me. And in this case, CI wins, hands down. Don’t get me wrong; Kohana is beautifully written and introduced me to a prime example of clean, well commented code. The devs are extremely intelligent and more talented than I’ll probably ever be. CI is also very clean, though there’s a bit more hacking involved for me to get it to work the way I like. However, I don’t want to be writing my own clean, well-commented code for one version of a framework only to find out the next version is going to totally break backwards compatibility. The lead Kohana devs have stated that there are no guarantees of stability between major versions (ie 1.x-2.x, etc). Comments like “well if it ain’t broke, don’t fix it” are dandy, but if part of the reason I’m using a framework is to let someone else worry about the basics for me, why would I stick with something that is no longer actively developed because the devs are on version 342.x?

While I respect progress and not letting code stagnate there’s something to be said for code stability when you’re maintaining a framework. Uber-optimising something is great (as there are repeated mentions of “x function is faster than w function” in the Kohana forums) but if it’s only saving me 0.02 ms of page load time or 0.25 mb memory, I’m not sure unstable code is worth that bit of extra speed. Furthermore, using an older codebase when you’re a one-(wo)man show can be a nightmare, since it’s a lot easier for one person to miss something than two, whether it’s a simple invalid method call or a glaring security hole.

I want to create apps to earn a living and I want to know that my code will stay more or less relevant between framework versions. API changes are to be expected between versions but complete rewrites, with very little thought for BC is just poor project management, IMO.

Please bear in mind that these are simply my views on the frameworks and my experiences and since I’m not a BDFL PHP guru (or something), you should perform your own research to see what works for you.

Update: I’ve posted a follow up post with some more thoughts (and such):

CakePHP 1.3, Smarty 3, and Theming. Woohoo!

There are various solutions out there for integrating Smarty with CakePHP. I’m here to introduce another one, that I feel is a little leaner than the other solutions I’ve found.

Jump to the code:


  • Cake 1.3.2 (No idea if it will work on < 1.3.2)
  • Smarty 3

Just place this in your /app/views folder andmake sure your AppController has the following lines:

public $view = "Theme";
public $layout = "default";
// The following line is optional; the default ext in the ThemeClass is set to .html.
// Uncomment to set to your desired extension
// public $ext = ".some_extension";

Your views would (unless you change the $ext variable) then be saved with .html extensions.