I've been a bit slow on the updates recently, been super busy with life and everything but thats no excuse. In my last article I went through the process of turning a Photoshop design into HTML/CSS and now its time to get CakePHP involved.
In this article I'm going to transfer the design and code over to CakePHP by using a new Layout and making use of some elements, this isn't necessarilly hard to do but the process it quite involved so I'm going to break it down.
Layouts
Have a quick read of the Layouts Chapter, basically a layout acts as a wrapper file with the code contained in your View files gets outputted in the "$content_for_layout" variable.In essence a layout saves you from writing out the DocType and head section of the HTML including all the links to your CSS and Javascript files. Layouts can also make use of special variables that allow you to change the Title of the page in your Controllers as well as include page specific Javascript. These variables are $title_for_layout and $scripts_for_layout respectively.
I've created a new layout file at /app/views/layout/index.ctp and it includes all the basic code for any HTML page. It has a DocType declaration along with a head and body section. The file also include the $title_for_layout variable and goes on to include all my CSS and Javascript files. As you can see I'm using the Cake helpers to link to the files.
Inside the body I'm using elements (which I'll cover very shortly) to include some header code, then echoing out my View code by using the $content_for_layout variable and finally use another element for a footer and close the body and html tag.
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title><?php echo $title_for_layout; ?></title>
- <?php
- // include css file
- echo $html->css('cakecatalog');
- // if the javscript helper is set include the javascript library
- if(isset($javascript)) {
- echo $javascript->link(array('jquery-1.2.3.pack', 'common'), true);
- }
- // variable for any other javascript
- echo $scripts_for_layout;
- ?>
- </head>
- <body>
- <?php
- // include a header element
- echo $this->element('index_header');
- // echo out view code
- echo $content_for_layout;
- // include a footer element
- echo $this->element('index_footer');
- // if debug is on echo to screen
- echo $cakeDebug;
- ?>
- </body>
- </html>
- // file: /app/controllers/dvds_controller.php
- // set page title
- $this->pageTitle = 'CakeCatalog - Index Page';
- // set layout file
- $this->layout = 'index';
Elements
Again have a quick read of the Elements Chapter in the Cookbook to get a greater understanding of what they're all about. Basically they work the same way as general PHP includes, small chunks of re-usable code that you can put in a seperate file to save you some time.I've created two Elements at /app/elements called index_header.ctp and index_footer.ctp and obviously they will contain code for the Header and Footer of my main page.
The Header element looks like this:
- // file: /app/views/elements/index_header.ctp
- <div id="wrapper-header">
- <div id="header">
- <div class="logo">
- <h1>CakeCatalog</h1>
- <h2>an online application to track and catalog your collection of dvds built using cakephp</h2>
- </div>
- <div class="filters">
- <form action="" method="post">
- <fieldset>
- <div class="input">
- <select>
- <option>Format</option>
- <option>Option 1</option>
- <option>Option 2</option>
- <option>Option 3</option>
- </select>
- </div>
- <div class="input">
- <select>
- <option>Type</option>
- <option>Option 1</option>
- <option>Option 2</option>
- <option>Option 3</option>
- </select>
- </div>
- <div class="input">
- <select>
- <option>Location</option>
- <option>Option 1</option>
- <option>Option 2</option>
- <option>Option 3</option>
- </select>
- </div>
- <div class="input">
- <select>
- <option>Genre</option>
- <option>Option 1</option>
- <option>Option 2</option>
- <option>Option 3</option>
- </select>
- </div>
- <div class="clear"></div>
- <div class="input">
- <input type="text" value="enter search items" />
- </div>
- <div class="input">
- <button type="submit" name="submit">Filter</button>
- <button type="reset" name="reset">Reset</button>
- </div>
- </fieldset>
- </form>
- </div>
- </div>
- </div>
- // file: /app/views/elements/index_footer.ctp
- <div id="wrapper-footer">
- <div id="footer">
- <div class="box top-rated">
- <h2>Top Rated</h2>
- <ol>
- <li><a href="">Desperado</a></li>
- <li><a href="">From Dusk Till Dawn</a></li>
- <li><a href="">Kill Bill Vol.1</a></li>
- <li><a href="">Pulp Fiction</a></li>
- <li><a href="">Reservior Dogs</a></li>
- </ol>
- </div>
- <div class="box recently-added">
- <h2>Recently Added</h2>
- <ol>
- <li><a href="">Desperado</a></li>
- <li><a href="">From Dusk Till Dawn</a></li>
- <li><a href="">Kill Bill Vol.1</a></li>
- <li><a href="">Pulp Fiction</a></li>
- <li><a href="">Reservior Dogs</a></li>
- </ol>
- </div>
- <div class="box top-genres">
- <h2>Top Genres</h2>
- <ol>
- <li><a href="">Desperado</a></li>
- <li><a href="">From Dusk Till Dawn</a></li>
- <li><a href="">Kill Bill Vol.1</a></li>
- <li><a href="">Pulp Fiction</a></li>
- <li><a href="">Reservior Dogs</a></li>
- </ol>
- </div>
- <div class="box most-active box-last">
- <h2>Most Active</h2>
- <ol>
- <li><a href="">Desperado</a></li>
- <li><a href="">From Dusk Till Dawn</a></li>
- <li><a href="">Kill Bill Vol.1</a></li>
- <li><a href="">Pulp Fiction</a></li>
- <li><a href="">Reservior Dogs</a></li>
- </ol>
- </div>
- <div class="clear"></div>
- <div class="copyright">
- <p>built using <a href="http://www.cakephp.org" target="_blank">CakePHP</a> by
- <a href="http://www.jamesfairhurst.co.uk" target="_blank">James Fairhurst</a></p>
- </div>
- </div>
- </div>
DVD's Index
In order to make the main contents work I need to wrap the entire View in my "wrapper" and "contents" divs so that when the View is rendered it will be placed inside the Layout and the CSS will kick in.- <div id="wrapper-contents">
- <div id="contents">
- <!-- dvd index page goes here -->
- </div>
- </div>
- <div class="shelf">
- <?php foreach($dvds as $key=>$dvd): ?>
- <?php
- // calculate if this dvd is the last on the shelf
- // if dvd number can be divided by 8 with no remainders
- $last_dvd = ( (($key+1) % 8 == 0)? 'dvd-last' : '' );
- ?>
- <div class="dvd <?php echo $last_dvd; ?>">
- </div>
- <?php
- // if this is the last dvd, close the shelf div and create a new one
- if(!empty($last_dvd)) {
- echo '<div class="clear"></div>';
- echo '</div>';
- echo '<div class="shelf">';
- }
- ?>
- <?php endforeach; ?>
- <div class="clear"></div>
- </div>
- // file: /app/views/dvds/index.ctp
- <div id="wrapper-contents">
- <div id="contents">
- <div class="dvds index">
- <?php
- // check $dvds variable exists and is not empty
- if(isset($dvds) && !empty($dvds)) :
- ?>
- <div class="shelf">
- <?php foreach($dvds as $key=>$dvd): ?>
- <?php
- // calculate if this dvd is the last on the shelf
- // if dvd number can be divided by 8 with no remainders
- $last_dvd = ( (($key+1) % 8 == 0)? 'dvd-last' : '' );
- ?>
- <div class="dvd<?php echo $last_dvd; ?>">
- <a href="/dvds/view/<?php echo $dvd['Dvd']['slug']; ?>">
- <img src="/<?php echo $dvd['Dvd']['image']; ?>" alt="DVD Image: <?php echo $dvd['Dvd']['name'] ?>" width="100" height="150" />
- </a>
- </div>
- <?php
- // if this is the last dvd, close the shelf div and create a new one
- if(!empty($last_dvd)) {
- echo '<div class="clear"></div>';
- echo '</div>';
- echo '<div class="shelf">';
- }
- ?>
- <?php endforeach; ?>
- <div class="clear"></div>
- </div>
- <?php
- else:
- echo 'There are currently no DVDs in the database.';
- endif;
- ?>
- </div>
- </div>
- </div>
CSS File and Images
To successfully reference your CSS and image files in CakePHP you must place the files in the /app/webroot directory, and I've organised the CSS, Images, Javascript into their own folders for organisation sake. You can then link to your images files in CSS as normal using the relative url:- // file: /app/webroot/css/cakecatalog.css
- #wrapper-header { background:url(../img/bg_header.png) repeat-x;}