<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Redmonster &#187; Applications</title>
	<atom:link href="http://www.goredmonster.com/topics/applications/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.goredmonster.com</link>
	<description>Agile Web Development</description>
	<lastBuildDate>Thu, 09 Jun 2011 21:09:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Making CakePHP Templates in TextMate</title>
		<link>http://www.goredmonster.com/cakephp/making-cakephp-templates-in-textmate/</link>
		<comments>http://www.goredmonster.com/cakephp/making-cakephp-templates-in-textmate/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 01:33:05 +0000</pubDate>
		<dc:creator>Paul Redmond</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://www.goredmonster.com/?p=228</guid>
		<description><![CDATA[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, [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to exploring <a href="http://manual.macromates.com/en/templates">templates</a> 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 <a href="http://manual.macromates.com/en/environment_variables.html">Environment Variables</a> in the <a href="http://manual.macromates.com/en/">TextMate manual</a>.</p>
<p>For the impatient: <a href="http://goredmonster.com/downloads/CakePHP.tmbundle.zip">download the bundle</a>. You should go through this post and make sure you set up shell variables properly. They are useful and worth understanding.</p>
<p>Most of my PHP development is done using the <a href="http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-web-designers/">CakePHP  framework</a>, and I prefer to create my own files rather than using the <a href="http://book.cakephp.org/view/113/Code-Generation-with-Bake">Bake console</a>. Just a personal preference. My templates are already proving to save time I would spend copying/pasting code. </p>
<p>Automating the creation of templates will save you time. Expensive time that you don&#8217;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.</p>
<h2>The Bundle Editor</h2>
<p>The bundle editor provides amazing functionality to TextMate. I&#8217;m convinced that the reason I work on a Mac is TextMate and the many customizable, automated features like bundles <img src='http://www.goredmonster.com/wp/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>To get our bundle started, fire up the bundle editor in <strong>Bundles > Bundle Editor > Show Bundle Editor</strong>. 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.<br />
<img src="http://www.goredmonster.com/wp/wp-content/uploads/2010/03/bundle_editor-300x141.gif" alt="TextMate Bundle Editor" title="TextMate Bundle Editor" width="300" height="141" class="size-medium wp-image-243" /></p>
<h2>Creating the Bundle and Template</h2>
<p>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&mdash;you&#8217;ll see how cool this feature is in a minute. Secondly, the actual template file that we will populate with our code.</p>
<ol>
<li>Create a new bundle by clicking the &#8220;+&#8221; icon on the bottom left of the TextMate bundle editor window and select &#8220;New Bundle&#8221;. Type in the name of the bundle; mine is called &#8220;CakePHP.&#8221;</li>
<li>Now that the bundle is created, highlight it, click the &#8220;+&#8221; icon again, and select &#8220;New Template.&#8221; Enter the name of your template; mine is &#8220;Controller.&#8221;</li>
<li>Highlight the template you just created and click the &#8220;+&#8221; icon one last time. Select &#8220;New template file&#8221;. It will be highlighted, name it something that matches the template and has the extension you want (in my case &#8220;.php&#8221;)</li>
</ol>
<p><img src="http://www.goredmonster.com/wp/wp-content/uploads/2010/03/cakephp-textmate-bundle.gif" alt="cakephp-textmate-bundle" title="cakephp-textmate-bundle" width="291" height="118" class="size-full wp-image-252" /></p>
<p>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&#8217;ll explain it afterwards:</p>
<pre>
&lt;?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){}

}
</pre>
<p>In my controller template, you will notice some dynamic elements and various actions/params that I use frequently in almost every controller.</p>
<p>The actual class name is generated by the file&#8217;s basename (the files name minus the extension) and is called <strong>${TM_CLASSNAME}</strong> 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 &#8220;UsersController&#8221; class file would be &#8220;users_controller.php&#8221; and the basename would be &#8220;users_controller&#8221;.</p>
<p>The template contains a variable called <strong>${TM_FULLNAME}</strong> which is generated by the full name of your TextMate licence. You can see this name by clicking <strong>TextMate > Registration</strong> from the menu. The field is called &#8220;Owner&#8221;.</p>
<p>The other variables will be created in the template script and through <a href="http://manual.macromates.com/en/environment_variables.html">shell variables (Section 9.2)</a>. 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&#8217;t think that they merely apply for this template only!</p>
<p>Let&#8217;s go ahead and create/update the shell variables this template will use:</p>
<ol>
<li>Navigate to <strong>TextMate > Preferences > Advanced</strong> and select Shell Variables.
<li>You should see a built-in shell variable called <strong>TM_ORGANIZATION_NAME</strong> with a made-up name. Edit the value of this field with the organization you want to appear in the block comment.</li>
<li>Create a new shell variable called &#8220;AUTHOR_EMAIL&#8221; and put in your email.</li>
</ol>
<p><img src="http://www.goredmonster.com/wp/wp-content/uploads/2010/03/shell_variables.gif" alt="TextMate shell variables" title="TextMate shell variables" width="458" height="410" class="alignnone size-full wp-image-264" /></p>
<p>You can now use <strong>${TM_ORGANIZATION_NAME}</strong> and <strong>${AUTHOR_EMAIL}</strong> in your templates.</p>
<h2>Template Script</h2>
<p>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):</p>
<p><img src="http://www.goredmonster.com/wp/wp-content/uploads/2010/03/controller_script.gif" alt="Controller bundle script" width="500" class="alignnone size-full wp-image-257" /></p>
<p>Here is the source for the Command(s) field:</p>
<pre>
#!/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
</pre>
<p><em>Note that I&#8217;m borrowing the camelize method from the <a href="http://api.rubyonrails.org/">Rails API</a></em></p>
<p>You don&#8217;t have to fully understand the ruby script I&#8217;m using, but there are a few things I&#8217;ll touch on to help you understand what is going on.</p>
<ol>
<li>I wanted to customize the date to include the exact time the file was created, so I used Ruby&#8217;s Time class to create <strong>ENV["TM_DATE_FULL"]</strong> with the <strong>strftime</strong> method. I can now use it in my template as <strong>${TM_DATE_FULL}</strong>.</li>
<li>To follow CakePHP&#8217;s convention of camel-case class names, I use the camelize method to camelize the basename of the file and assign to <strong>ENV["TM_CLASSNAME"]</strong>.</li>
<li>The <em>$name</em> param of a CakePHP controller is the same as the class name, but omits &#8220;controller&#8221;, so I am splitting the file basename at &#8216;_controller&#8217; and joining the first part back to a string; this string is also camel-cased using the camelize method.</li>
</li>
</ol>
<p>The names match the custom fields in the template file&mdash;remember that they are <em>case-sensitive</em>.</p>
<p>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 &#8220;Test&#8221; button in the bundle editor template script.</p>
<p>We&#8217;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 &#8220;create&#8221;.<br />
<img src="http://www.goredmonster.com/wp/wp-content/uploads/2010/03/textmate_new_from_template.gif" alt="textmate_new_from_template" title="textmate_new_from_template" width="380" height="181" class="alignnone size-full wp-image-274" /></p>
<p>I hope this is useful for others, it really improved my workflow. My <a href="http://goredmonster.com/downloads/CakePHP.tmbundle.zip">bundle download</a> also contains a model template too, so be sure to check out the bundle code in your new friend, the bundle editor.</p>
<h2>Other Great Textmate Bundles</h2>
<p>Some other textmate bundles I really cannot live without:</p>
<ul>
<li><a href="http://github.com/protocool/ack-tmbundle">Ack in Project</a></li>
<li><a href="http://code.google.com/p/zen-coding/">Zen Coding</a></li>
<li><a href="http://www.campaignmonitor.com/downloads/textmate-email-bundle/">TextMate Email Bundle</a></li>
</ul>

<!-- Start TwitterButton -->
<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script><div class="twitter-button"><a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-url="http://www.goredmonster.com/cakephp/making-cakephp-templates-in-textmate/" data-via="goredmonster" data-text="Making CakePHP Templates in TextMate">Tweet</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.goredmonster.com/cakephp/making-cakephp-templates-in-textmate/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

