Hello, I'm Paul.

I specialize in web design and online marketing. This site focuses on web design, web usablility, and development. I've been working on the web since 2002.

Learn More about this Site

Redmonster is a blog about web design, programming, and internet marketing. It's also the home to my Wordpress Plugins and other experiments.

latest blog post

Making CakePHP Templates in TextMate

March 7th, 2010

I finally got around to exploring templates in the TextMate bundle editor. The PHP bundle does not have any templates, and so I set out to create a few to improve my workflow. I thought it would be helpful information for PHP developers using TextMate. I actually used the Ruby interpreter to power my templates, but you can definately use PHP, or any other interpreter you like (Python, Perl, etc.). You might want to check out Environment Variables in the TextMate manual.

For the impatient: download the bundle. You should go through this post and make sure you set up shell variables properly. They are useful and worth understanding.

Most of my PHP development is done using the CakePHP framework, and I prefer to create my own files rather than using the Bake console. Just a personal preference. My templates are already proving to save time I would spend copying/pasting code.

Automating the creation of templates will save you time. Expensive time that you don’t need to waste on repetitive stuff. You can even modify the existing templates provided in the bundle editor. I know virtually every HTML document I create will need at least one stylesheet, meta data, and scripts.

The Bundle Editor

The bundle editor provides amazing functionality to TextMate. I’m convinced that the reason I work on a Mac is TextMate and the many customizable, automated features like bundles ;) .

To get our bundle started, fire up the bundle editor in Bundles > Bundle Editor > Show Bundle Editor. You could also use the shortcut, Control + Option + Command + B (the bottom three modifier keys + B). The bundle editor allows you to create snippets, macros, drag commands, templates, etc.
TextMate Bundle Editor

Creating the Bundle and Template

Templates require a few things to work. Firstly, a script that actually processes the template, allowing you to generate dynamic template elements on the fly—you’ll see how cool this feature is in a minute. Secondly, the actual template file that we will populate with our code.

  1. Create a new bundle by clicking the “+” icon on the bottom left of the TextMate bundle editor window and select “New Bundle”. Type in the name of the bundle; mine is called “CakePHP.”
  2. Now that the bundle is created, highlight it, click the “+” icon again, and select “New Template.” Enter the name of your template; mine is “Controller.”
  3. Highlight the template you just created and click the “+” icon one last time. Select “New template file”. It will be highlighted, name it something that matches the template and has the extension you want (in my case “.php”)

cakephp-textmate-bundle

Your bundle should look similar to mine. Now that the template script and template file are created, highlight the template file (mine is controller.php). Paste in the following code, I’ll explain it afterwards:

<?php
/**
 * Description
 *
 * Copyright ${TM_YEAR}, ${TM_ORGANIZATION_NAME}. All Rights Reserved.
 *
 * @author ${TM_FULLNAME} <${AUTHOR_EMAIL}>
 * @created ${TM_DATE_FULL}
 */
class ${TM_CLASSNAME} extends AppController {
	/**
	 *
	 */
	public $name = '${TM_NAME_PARAM}';
	/**
	 *
	 */
	public $helpers = array();
	/**
	 *
	 */
	public $components = array();

	## Public Actions

	/**
	 *
	 */
	public function index() {}

	/**
	 *
	 */
	public function view($id=null){}

	## Admin Actions

	/**
	 *
	 */
	public function admin_index() {}

	/**
	 *
	 */
	public function admin_edit($id=null){}

	/**
	 *
	 */
	public function admin_delete($id=null){}

}

In my controller template, you will notice some dynamic elements and various actions/params that I use frequently in almost every controller.

The actual class name is generated by the file’s basename (the files name minus the extension) and is called ${TM_CLASSNAME} in the template. The basename variable is automatically available to templates. Those of you familiar with CakePHP will know that controller filenames use underscores. So the “UsersController” class file would be “users_controller.php” and the basename would be “users_controller”.

The template contains a variable called ${TM_FULLNAME} which is generated by the full name of your TextMate licence. You can see this name by clicking TextMate > Registration from the menu. The field is called “Owner”.

The other variables will be created in the template script and through shell variables (Section 9.2). Shell variables are reusable variables assigned in the preferences. These are really cool, because you can use them throughout the TextMate application. You can also create project-specific shell variables in your TextMate projects. Don’t think that they merely apply for this template only!

Let’s go ahead and create/update the shell variables this template will use:

  1. Navigate to TextMate > Preferences > Advanced and select Shell Variables.
  2. You should see a built-in shell variable called TM_ORGANIZATION_NAME with a made-up name. Edit the value of this field with the organization you want to appear in the block comment.
  3. Create a new shell variable called “AUTHOR_EMAIL” and put in your email.

TextMate shell variables

You can now use ${TM_ORGANIZATION_NAME} and ${AUTHOR_EMAIL} in your templates.

Template Script

The template script is where the real magic happens in our template. Select the template script of your bundle, and you will see a few fields. Update the fields with the following (see source code below image to copy):

Controller bundle script

Here is the source for the Command(s) field:

#!/usr/bin/env ruby -wKU

# METHODS
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
	if first_letter_in_uppercase
         lower_case_and_underscored_word.to_s.gsub(/\/(.?)/)
             { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
    else
    	lower_case_and_underscored_word.first.downcase +
            camelize(lower_case_and_underscored_word)[1..-1]
    end
end

f = open(ENV["TM_NEW_FILE"], 'w')
template = open("controller.php").read

ENV["TM_YEAR"] = `date +%Y`.chomp
ENV["TM_DATE"] = `date +%Y-%m-%d`.chomp
ENV["TM_DATE_FULL"] = Time.now.strftime("%m-%d-%Y %I:%M %p")
basename = ENV['TM_NEW_FILE_BASENAME']

ENV["TM_CLASSNAME"] = camelize(basename)
ENV["TM_NAME_PARAM"] = camelize(basename.split('_controller').join)

if ENV["TM_SOFT_TABS"] == "YES"
	tab_size = ENV["TM_TAB_SIZE"].to_i
	tab_size = tab_size ? tab_size : 4
	template = template.gsub(/\t/, " "*tab_size)
end

template = template.gsub(/[$]\{([^}]+)\}/){|match| "#{ENV[$1]}" }
f.write template
f.close

Note that I’m borrowing the camelize method from the Rails API

You don’t have to fully understand the ruby script I’m using, but there are a few things I’ll touch on to help you understand what is going on.

  1. I wanted to customize the date to include the exact time the file was created, so I used Ruby’s Time class to create ENV["TM_DATE_FULL"] with the strftime method. I can now use it in my template as ${TM_DATE_FULL}.
  2. To follow CakePHP’s convention of camel-case class names, I use the camelize method to camelize the basename of the file and assign to ENV["TM_CLASSNAME"].
  3. The $name param of a CakePHP controller is the same as the class name, but omits “controller”, so I am splitting the file basename at ‘_controller’ and joining the first part back to a string; this string is also camel-cased using the camelize method.

The names match the custom fields in the template file—remember that they are case-sensitive.

Now when you create a new controller in a CakePHP project you can take advantage of your new template. Make sure all your template settings match my code above. You can test a template by clicking the “Test” button in the bundle editor template script.

We’re done. Create a new file in your TextMate project (Shift + Command + N in a project), select the template we just created from the dropdown, and click “create”.
textmate_new_from_template

I hope this is useful for others, it really improved my workflow. My bundle download also contains a model template too, so be sure to check out the bundle code in your new friend, the bundle editor.

Other Great Textmate Bundles

Some other textmate bundles I really cannot live without:

Recent Posts

Introduction to CakePHP for Designers: Part II

March 1st, 2010

In the first tutorial, I covered basic foundations of views, and set out create a simple task management application. This tutorial will focus on controllers, which interact with both views and models. The process of the MVC framework is a simple paradigm, where controllers handle requests, get data from the model as needed, and process [...]

Introduction to CakePHP for Web Designers

December 8th, 2009

CakePHP hits the sweet-spot for many of my projects. The conventions and “baked” in classes are huge productivity boosters. Even if you just intend of working with visual elements on a CakePHP project (views), this series will walk you through hands-on lessons of building a simple task management application with CakePHP.

Official WordPress WP-EmailCrypt Plugin Page

November 19th, 2009

My first official WordPress plugin, Wp-EmailCrypt, is now live on Wordpress.org. Wp-EmailCrypt automatically converts email links into encrypted JavaScript code, and reduces the likelihood of emails being harvested.

My New Wordpress Plugin – Wp-Emailcrypt

November 17th, 2009

I finally got around to submitting my WordPress plugin for encrypting emails: Wp-Emailcrypt. It should be on the official wordpress.org plugin site soon (if they approve it ;) , but I would like anyone that uses WordPress to try it out. Let me know what you think.

http://www.goredmonster.com/projects/wp-emailcrypt/

Shrink your JavaScript/CSS in Wordpress with PHP

October 24th, 2009

I came across a very simple, yet elegant solution for shrinking JavaScript and CSS files with PHP. When large JavaScript frameworks are the order of the day, why not optimize? In this post I’ll show you how to easily apply this script to your Wordpress theme; shrinking your CSS/JavaScript assets by around 300%!

Welcome to Redmonster

October 24th, 2009

Welcome to Goredmonster.com! I will be blogging here about web design and development. I will be writing about various topics, but I will focus on PHP, Wordpress, CakePHP, and JavaScript. Of course, I plan on releasing various Wordpress plugins and will write about them.

Web Stuff I Highly Recommend

Basecamp Media Temple(MT)