Tuesday, August 21, 2012

My CodeIgniter + Bootstrap starter kit


I thought I would share my CodeIgniter + Bootstrap starter kit.

Highlights:
- CodeIgniter 2.1.0 codebase included
- Bootstrap 2.0.3 theme with its JS extensions in a single file
- jquery 1.7.1 and knockout 2.1 included
- default controller: home/start.php; default view: home/start.php

To use, it just drop inside your /htdoc or /var/www folder.

Download the zipped file or clone it from my bitbucket mercurial repo. To clone:

hg clone https://bitbucket.org/jaypax/cibootstrap

Have fun with it.

Updated 9/29/2012

  • Updated Bootstrap to 2.1.0 
  • Added bootstrap-responsive.css (min version included)
  • Updated CodeIgniter to 2.1.2 
  • Added underscore.js 
  • Added underscore-ko.min.js (see https://github.com/kamranayub/UnderscoreKO
  • Added jquery-1.7.1-vsdoc.js

Friday, August 17, 2012

Autobind All Tapestry5 services!

Norman Franke, Dmitry Gusev and a bunch of other guys in the Tapestry5 mailing list show us a very cool way to bind services via package traversal. No more binder declarations for DAO services several miles long.

The technique they showed made me want to smack my older self - Why didn't you think of that!? This autobind technique basically just needs a bit of planning - a "convention" if you will. The idea is to put the "implementation" package as a folder below your DAO interfaces. Typically, you would append an "Impl" tag to your DAO interfaces so for example: UserDAO = UserDAOImpl and then place them in the correct packages: com.myapp.dao for the DAO interfaces and then com.myapp.dao.impl for the DAO implementations. The rest is done in the AppModule of Tapestry5.

...
public static void Bind(ServiceBinder binder) throws ClassNotFoundException  
{  
   autoBindServices(binder, ProjectDAO.class.getPackage());  
   .....  
}  
private static void autoBindServices(ServiceBinder binder, Package interfacePackage) throws ClassNotFoundException  
{  
  List<Class<?>> interfaces = Utils.getClassesForPackage(interfacePackage.getName());  
  for(Class intf : interfaces)  
  {  
     String className = interfacesPackage.getName() + ".impl." + intf.getSimpleName() + "Impl";  
     try  
     {  
         Class impl = Class.forName(className);  
         binder.bind(intf, impl);  
     }  
     catch(ClassNotFoundException e)  
     {  
         logger.warn("Class not found during autobinding: {}", className);  
     }  
  }  
}
Very cool stuff.