<?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; CakePHP</title>
	<atom:link href="http://www.goredmonster.com/topics/cakephp/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>
		<item>
		<title>Introduction to CakePHP for Designers: Part II</title>
		<link>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-designers-part-ii/</link>
		<comments>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-designers-part-ii/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 06:49:07 +0000</pubDate>
		<dc:creator>Paul Redmond</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.goredmonster.com/?p=191</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-web-designers/">first tutorial</a>, I covered basic foundations of views, and set out create a simple task management application. This tutorial will focus on <strong>controllers</strong>, 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 the request by giving feedback to the user through views. Controllers play an important middle-man role in MVC applications.</p>
<p>To help illustrate the role controllers play, consider a bank. Customers request information from the bank through ATMs, online banking websites, and bank employees. Customers don’t have direct access to the bank’s safe, they must request this information from ATMs and bank tellers, etc. ATMs and tellers represent the controller in our analogy. They facilitate the requests of customers by accessing account information and money. This information is then processed and returned to the customer. In the same way, users of an MVC application make requests to the controller through views. These requests are received by the controller. The controller requests data from the database through models. Controllers then return data to views.</p>
<p>CakePHP controllers work closely with models to facilitate data from the database. This means we need to create a database and a table to get our controller working. We could bypass the model (controllers don&#8217;t technically need models in some cases) and just use our controller, but that would only be confusing to those learning the importance of controllers in working with both models and views.</p>
<p>Lets start by creating a database. For simplicity, lets name the database “taskmaster” (I know, totally cheezy :-/). You should have a working MySQL database server running. This tutorial will not go into the details of setting up MySQL and PHP. Fire up your favorite MySQL management tool, or use the handy terminal if that suits you. I’m going to type the following to login via the terminal:</p>
<pre>mysql -u root -p</pre>
<p>MySQL will prompt you for a password. Once you type in your password (default is blank, or no password) you will see the mysql prompt. Type in:</p>
<pre>create database taskmaster;</pre>
<p>Don’t forget the semi-colon! Verify that the database was created by typing in:</p>
<pre>show databases</pre>
<p>Now that we have our database created, lets create a table. Enter the following query to create your first table.</p>
<pre>
CREATE TABLE `tasks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `description` varchar(255) NOT NULL,
  `completed` tinyint(1) DEFAULT '0',
  `created` datetime,
  `modified` datetime,
  PRIMARY KEY (`id`)
);
</pre>
<p>This might seem like a simple table, but there are a few important conventions that CakePHP will reward. The table name “tasks” will ensure that we can create a controller called “TasksController” and a model called “Task”. We don’t have to do much configuration to start working with our data if we use these naming conventions. The lowercase id field is standard on any table in CakePHP. Created and modified columns will be automatically updated by CakePHP when we save a new record or update one. We don’t even have to worry about these columns when saving data.</p>
<p>Lets create a few records so we have actual data to retrieve from our model via the controller. Run the following queries to get some tasks in the tasks table:</p>
<pre>
INSERT INTO tasks (description, created, modified)
    VALUES ('Take out the trash.', NOW(), NOW());
INSERT INTO tasks (description, created, modified)
    VALUES ('Wash the car.', NOW(), NOW());
</pre>
<p><em>Note: I added NOW() twice to simulate what CakePHP will do when we create a new task within the application.</em></p>
<p>Now that our table is created and has a few tasks entered, lets jump over to our CakePHP application. The first order of business is telling CakePHP about our database. Navigate to app/config/database.php and change the default connection to match your database information. Mine looks like the following:</p>
<pre>
var $default = array(
	'driver' => 'mysql',
	'persistent' => false,
	'host' => 'localhost',
	'login' => 'root',
	'password' => '',
	'database' => 'taskmaster',
	'prefix' => '',
);
</pre>
<p>Create a new file in app/controllers called tasks_controller.php and populate with the following code:</p>
<pre>
&lt;?php
class TasksController extends AppController {
	public $name = ‘Tasks’;

	public function index() {

	}
}
</pre>
<p>I’ve added an empty function for our default action. As you will see shortly, functions in controllers are actions requested by users through a URL. Index is the default action for any controller unless you specify otherwise in app/config/routes.php. Controller class names are camel-cased, and the file names use underscores, which is why TasksController’s filename is tasks_controller.php. Controllers are generally named the same as the name of the database table.</p>
<p>Now we need to create a model file. Create a new file in app/models called task.php and populate with the following:</p>
<pre>
&lt;?php
class Task extends AppModel {
	public $name = ‘Task’;
}
</pre>
<p>We now have a skeleton model and controller. Since we have data, lets write our controller code to get our tasks from the database and then display them in the view. Our controller will request tasks from the tasks table, and for now, we will request all tasks (we only have two so far after all). Your tasks controller will look like this:</p>
<pre>
&lt;?php
public function index() {
	$tasks = $this->Task->find('all');
	$this->set('tasks', $tasks);
}
</pre>
<p>We are getting all tasks in the database, using the Task model. $this->Task represents the model we just created. Both our controllers and models inherit a bunch of built-in functionality from AppController and AppModel. <br />$this->Task->find() is one such method. The controller then sets a variable for the view called “tasks” and is populated with an associative array that was returned from the find method. We have everything we need to display model data in the view&#8230;let’s get going!</p>
<p>Create a folder in app/views called tasks. This folder name also matches the controller name, which keeps our views organized. In the newly created folder, create a file called index.ctp, which matches our index function in TasksController, and paste the following:</p>
<pre>
&lt;h1&gt;Tasks&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
		&lt;tr&gt;
			&lt;th scope="col"&gt;Id&lt;/th&gt;
			&lt;th scope="col"&gt;Description&lt;/th&gt;
			&lt;th scope="col"&gt;Complete?&lt;/th&gt;
			&lt;th scope="col"&gt;Created&lt;/th&gt;
			&lt;th scope="col"&gt;Modified&lt;/th&gt;
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
	&lt;?php foreach($tasks as $task):
		$completed = $task['Task']['completed'] == FALSE ? 'No' : 'Yes';
	?&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;?php echo $task['Task']['id']; ?&gt;&lt;/td&gt;
			&lt;td&gt;&lt;?php echo $task['Task']['description']; ?&gt;&lt;/td&gt;
			&lt;td&gt;&lt;?php echo $completed; ?&gt; &lt;/td&gt;
			&lt;td&gt;&lt;?php echo $task['Task']['created']; ?&gt;&lt;/td&gt;
			&lt;td&gt;&lt;?php echo $task['Task']['modified']; ?&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;?php endforeach; ?&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
</pre>
<p>You can now see the index action of our controller by navigating to the url of your application. Mine is <strong>http://localhost/cakephp-designers/tasks</strong>. The url contains our controller name &#8220;tasks&#8221;. You can omit the &#8220;index&#8221; action from the url because, like I mentioned above, index is the default action.</p>
<p>To illustrate how URLs match functions in a controller, you can navigate to http://localhost/cakephp-designers/tasks/index and get the same page. An add action might have this URL: http://localhost/cakephp-designers/tasks/add and would call a function called &#8220;add&#8221; in the TasksController class.</p>
<p>Our plain vanilla table has a foreach loop that loops through the data supplied from the controller that was assigned to a variable called tasks. It is important to understand the array structure that CakePHP returns when retrieving data from models. You can view the array by adding debug($tasks); in the view. You must have debugging turned on to see the array. You will notice that each record is contained in an associative array, where the key matches the model, or “Task”.</p>
<p>We now have a very simple, but functional controller. Our next tutorial will focus on learning about the form helper, getting data into our database from a form, validating that data through the model, and furthering your understanding of models and controllers in general. Until next time!</p>

<!-- 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/introduction-to-cakephp-for-designers-part-ii/" data-via="goredmonster" data-text="Introduction to CakePHP for Designers: Part II">Tweet</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-designers-part-ii/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Introduction to CakePHP for Web Designers</title>
		<link>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-web-designers/</link>
		<comments>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-web-designers/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 06:00:59 +0000</pubDate>
		<dc:creator>Paul Redmond</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.goredmonster.com/?p=165</guid>
		<description><![CDATA[
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.]]></description>
			<content:encoded><![CDATA[<p>CakePHP for web designers, is a series of hands-on tutorials that help new programers and those with a design background understand the basics of CakePHP. There is plenty of theory and API documentation out there on the web; I’d rather spend my time writing about hands-on examples of how you can start using CakePHP today.</p>
<p>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.</p>
<h2>Installing CakePHP</h2>
<p>This series is focused on working with CakePHP, so I don’t want PHP installation interfering with the content of this series. I’ve included installation notes at the bottom of this tutorial to get Apache, PHP, MySQL going. For a full explanation of how to get CakePHP set up properly, see section <a title="CakePHP Requirements" href="http://book.cakephp.org/view/28/Requirements">3.1</a>, <a title="CakePHP Installation Preparation" href="http://book.cakephp.org/view/29/Installation-Preparation">3.2</a>, <a title="CakePHP Installation" href="http://book.cakephp.org/view/32/Installation">3.3</a> and <a title="CakePHP Configuration" href="http://book.cakephp.org/view/39/Configuration">3.4</a> of the <a href="http://book.cakephp.org/">CakePHP book</a>.</p>
<p>In a nutshell, you will download CakePHP’s latest stable version at <a href="http://cakephp.org">http://cakephp.org</a> and upload the files somewhere inside the apache document root on your development machine. I’ve installed a fresh version on http://localhost/cakephp-designers/</p>
<p><img class="alignleft size-medium wp-image-169" title="cakephp_designers_01" src="http://www.goredmonster.com/wp/wp-content/uploads/2009/12/cakephp_designers_01-300x234.png" alt="cakephp_designers_01" width="300" height="234" /></p>
<p>What you see in screenshot #1 is the default CakePHP page with info about your environment configuration. Obviously, we don’t want this to be the homepage of our website, but it’s nice to see something when we get CakePHP installed correctly. This page has useful information about your configuration, and potentially, gives you warnings of steps you missed during setup.</p>
<p>CakePHP applications follow the <a href="http://book.cakephp.org/view/10/Understanding-Model-View-Controller">MVC software design pattern</a> which we will tackle later in this series. Learning the MVC software paradigm is essential to using CakePHP, and the payoff is clean code that is more secure and easier to maintain. This post will be focusing on the “V” in MVC, or the View.</p>
<p>Navigate to your project’s app &gt; views folder. Create a folder called “pages” and inside pages, create a file called “about.ctp”. The file extension “.ctp” is CakePHP view files and accepts HTML and PHP code. Lets add a basic placeholder for our about page in about.ctp:</p>
<pre>&lt;h1&gt;About&lt;/h1&gt;
&lt;p&gt;This is the about page for our application&lt;/p&gt;</pre>
<p>Navigate to your newly create page by navigating to your project url. Mine is http://localhost/cakephp-designers/pages/about Notice that our page is displaying much more than our simple HTML. View the source and you will see the entire HTML structure of your project. The doctype and other HTML code belong to the layout.</p>
<h2>Your Layout</h2>
<p>Right now our project is using the built-in CakePHP layout, but we want to work with our own layout. By default, CakePHP looks for default.ctp in app &gt; views &gt; layouts but if you look in your project you will not find default.ctp anywhere. Create default.ctp and throw in the following HTML:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Tasks&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;?php echo $content_for_layout; ?&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Nothing special here except $content_for_layout. This variable is the output of your view. If you browse to your about page now, you will see the new template in action, and and unstyled site.</p>
<p>Create two more pages, in app &gt; views &gt; pages called index.ctp and contact.ctp and paste in the following:</p>
<pre>&lt;h1&gt;Contact Us&lt;/h1&gt;
&lt;p&gt;Contact info for our application will go here.&lt;/p&gt;</pre>
<p>and</p>
<pre>&lt;h1&gt;Welcome!&lt;/h1&gt;
&lt;p&gt;Welcome to my task management site.&lt;/p&gt;</pre>
<h2>Linking</h2>
<p>Now we have three separate pages, but no way to navigate between each page. CakePHP has a built-in helper called the HTML Helper that makes navigation links within a CakePHP application a breeze; and you can be certain that your links will always work when you follow conventions, no matter where the application resides.</p>
<p>We could easily create static anchor tags and call it a day, but we would be penalized in the future when we update our routes.php file or if we moved the application to another location. With static HTML links, all links would have to be manually updated each time routes.php was modified with a custom URL pattern.</p>
<p>Lets build the navigation using CakePHP conventions. Open default.ctp and add the navigation to this file so it will always appear in any view using default.ctp:</p>
<pre>&lt;div id="navigation"&gt;
	&lt;?php echo $html-&gt;link('Home',
            array('controller' =&gt; 'pages', 'action' =&gt; 'index')); ?&gt; |
	&lt;?php echo $html-&gt;link('About',
            array('controller' =&gt; 'pages', 'action' =&gt; 'about')); ?&gt; |
	&lt;?php echo $html-&gt;link('Contact Us',
            array('controller' =&gt; 'pages', 'action' =&gt; 'contact')); ?&gt;
&lt;/div&gt;</pre>
<p><img class="size-medium wp-image-170 alignright" title="cakephp_designers_02" src="http://www.goredmonster.com/wp/wp-content/uploads/2009/12/cakephp_designers_02-300x166.png" alt="cakephp_designers_02" width="300" height="166" /></p>
<p>If you view your project in a web browser, you will notice the magic that CakePHP performed. All the links were generated with the correct url. Unfortunately, if you click on the home link, it goes to the default CakePHP screen. We can fix that with routes.php.</p>
<h2>Routes</h2>
<p>Routes are an advanced topic, so we will only lightly touch on their power. Routes enable you to do magical things with your URLs and how those URLs relate to your application logic. For now, we only want our index.ctp file to be the homepage our our application. Open routes.php in app &gt; config folder. Around line 34, you should see the default route for the homepage. Lets modify it from this:</p>
<pre>Router::connect('/', array('controller' =&gt; 'pages', 'action' =&gt; 'display', 'home'));</pre>
<p>to this:</p>
<pre>Router::connect('/', array('controller' =&gt; 'pages', 'action' =&gt; 'display', 'index'));</pre>
<p>Save and close routes.php. Make sure you only modify the above code&#8211;this file is critical to CakePHP. The routes.php file now considers index.ctp the homepage of the application, and you will now see your homepage in your web browser.</p>
<h2>Styling Your Application</h2>
<p>To conclude this tutorial, lets add some basic styles to our application. Your website assets are all located in app &gt; webroot in their respective folders. The Webroot folder is the webroot of your application, so http://localhost/cakephp-designers/css in our project points to app &gt; webroot &gt; css.</p>
<p>Browse to app &gt; webroot &gt; css and create a file called style.css. You will also notice cake.generic.css which is the default css file used on the default homepage.</p>
<p>Add the following CSS rules to style.css:</p>
<pre>body {
	background: #ddd;
	font: 12px "Lucida Grande", "Trebuchet Ms", sans-serif;
}
#wrap {
	margin: 20px auto;
	background: #fff;
	width: 800px;
}
#navigation, #footer {
	background: #333;
	padding: 8px 10px;
	color: #fff;
}
#navigation a {
	color: #fff;
	text-decoration: none;
	font-size: 14px;
	margin: 0 15px;
}
#content {
	padding: 5px 20px;
}
#content h2 {
	margin: 0;
}
#footer {
	font-size: 11px;
}</pre>
<p>Update default.ctp to match the following:</p>
<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Tasks&lt;/title&gt;
	&lt;?php echo $html-&gt;css(array('style.css')); ?&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id="wrap"&gt;
		&lt;div id="navigation"&gt;
			&lt;?php echo $html-&gt;link('Home',
                            array('controller' =&gt; 'pages',
                            'action' =&gt; 'index')); ?&gt; |
			&lt;?php echo $html-&gt;link('About',
                            array('controller' =&gt; 'pages',
                            'action' =&gt; 'about')); ?&gt; |
			&lt;?php echo $html-&gt;link('Contact Us',
                            array('controller' =&gt; 'pages',
                            'action' =&gt; 'contact')); ?&gt;
		&lt;/div&gt;
		&lt;div id="content"&gt;&lt;?php echo $content_for_layout; ?&gt;&lt;/div&gt;
		&lt;div id="footer"&gt;
                    Copyright © &lt;?php echo date("Y"); ?&gt;. All Rights Reserved.
                &lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p><img class="alignleft size-medium wp-image-171" title="cakephp_designers_03" src="http://www.goredmonster.com/wp/wp-content/uploads/2009/12/cakephp_designers_03-300x136.png" alt="cakephp_designers_03" width="300" height="136" /></p>
<p>There are some new things in default.ctp that you might have noticed. In the  of the document, I used another HTML helper method called “css” which generates a link tag to each css file listed in the array. This method automatically links to our css files in the webroot folder. This requires no additional configuration in the future, and is an important convention in CakePHP. I also threw in a date() function to show off vanilla PHP in our templates =).</p>
<p>Now our application is beginning to look alive, but in a boring, static way. Our next tutorial in this series will fix that, as we cover models and controllers. We must cover both simultaneously as models and controllers work closely together to deliver dynamic data in view files.</p>
<h2>Conclusion</h2>
<p>We just tapped the surface of the powerful features of CakePHP views. CakePHP has made it easier to create a consistent workflow for designers and developers. As you will begin to understand, following CakePHP and MVC conventions make life easier for future developers working on your applications.</p>
<p>We’ve covered a vast amount in a short span, but most of the learning will come from experimenting and diving into the code. Please feel free to ask questions in the comments or email me directly.</p>
<p><strong>Notes:</strong><br />CakePHP has a few requirements (http://book.cakephp.org/view/28/Requirements), which will work with pretty much any machine. In a nutshell, you need to configure Apache (enable mod_rewrite), PHP 5, and MySQL to get CakePHP going. CakePHP is flexible and compatible with both PHP 4 and PHP 5. Please use PHP 5. Please? Thank you.</p>
<p>My favorite guide for installing Apache, PHP, and MySQL is contained in <a href="http://foundationphp.com/phpsolutions/">PHP Solutions</a> by David Powers. I recommend purchasing this book if you are just learning how to program PHP. David Powers is a wonderful instructor, and the book does a marvelous job of teaching new programmers PHP. Other more simple solutions include MAMP (mac) and <a href="http://www.microsoft.com/WEB/platform/phponwindows.aspx">PHP on Windows</a> for Windows users. I am assuming Linux users can get LAMP going and don’t need advice <img src='http://www.goredmonster.com/wp/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Depending on your configuration, you might need to add RewriteBase /path/to/your/cake/files/ to each of your .htaccess files to get CakePHP url rewriting to work properly. If you give up on getting this working, you can open app &gt; config &gt; core.php and uncomment line #57 //Configure::write(&#8216;App.baseUrl&#8217;, env(&#8216;SCRIPT_NAME&#8217;));. You must also delete all .htaccess files to not use mod_rewrite.</p>

<!-- 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/introduction-to-cakephp-for-web-designers/" data-via="goredmonster" data-text="Introduction to CakePHP for Web Designers">Tweet</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.goredmonster.com/cakephp/introduction-to-cakephp-for-web-designers/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

