 | Using the Bake code generator
It's not necessary to completely throw away everything scaffolding
gives you. By using Bake, the CakePHP code generator, you can generate
a controller that contains functions that represent the scaffolding
functionality and the views to go with it. For the products-related
parts of Tor, this will be a huge time-saver.
In CakePHP V1.1, Bake was a PHP script you called directly. In
CakePHP V1.2, the Bake functionality has been moved to the Cake
Console, which you will be getting familiar with through the rest of
this tutorial. You can simplify your life if you add the path
/webroot/cake/console to your environment's
PATH variable. This will allow you to call
the Cake Console without specifying path information. You don't need
to do this, and the tutorial will assume you have not. Additionally,
you should run the Cake Console from your application's app directory
— in this case, /webroot/app — or the Cake Console
will think you are trying to do something new.
Before you proceed, make a copy of your existing app directory. Bake
will overwrite the products controller, and you should always back up
your files when an operation involves the word "overwrite" (or the
words "copy," "delete," "format," or "voodoo"). If you have problems
getting this to run, make sure the php
executable is in your environment's PATH
variable.
Baking your products
controller
To use Bake, cd into the /webroot/app
directory and launch the Cake Console:
../cake/console/cake bake. You should be
presented with a screen that looks like Figure 2.
Figure 2. Bake menu
For the Tor application, the model you've written should be fine, so
let's start with the controller. Press C to select the
controller. The Cake Console will take a look at the application as it
stands and present a list of possible controllers you may want to
bake.
Figure 3. Controller name
In this case, you are baking the products controller, which should be
controller No. 2. Bake will ask if you want to build the
controller interactively. For now, press N to let Bake make all
the decisions on its own, but later on, you should try building a
controller interactively to get a feel for what Bake can do for you
beyond this. Bake will then ask if you want to include some basic
class methods (see Figure 4). Press Y
— getting this code is the whole reason you are here. Next,
Bake will ask it you want to create methods for admin routing. Press
N
— you don't need these right now. Bake will ask you to confirm
the controller before continuing. When you continue, Bake will make
sure you want to overwrite the existing controller (in this case, you
do). Bake should then inform you that it's created the file
\app\controllers\products_controller.php and ask if you want to bake
some unit test files. You can skip these for now. Once you are done,
you will be returned to the Bake menu.
Figure 4. Controller
created
That's all there is to it. Exit the Cake Console, open up
app/controllers/products_controller.php and take a look at what Bake
did for you. It should look something like Listing 8.
Listing 8. products_controller.php after Bake
class ProductsController extends AppController {
var $name = 'Products';
var $helpers = array('Html', 'Form' );
function index() {
$this->Product->recursive = 0;
$this->set('products', $this->paginate());
}
function view($id = null) {
if (!$id) {
$this->Session->setFlash('Invalid Product.');
$this->redirect(array('action'=>'index'));
}
$this->set('product', $this->Product->read(null, $id));
}
function add() {
if (!empty($this->data)) {
$this->Product->create();
if ($this->Product->save($this->data)) {
$this->Session->setFlash( ('The Product has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash('The Product could not be
saved. Please, try again.', true))
}
}
$dealers = $this->Product->Dealer-find('list');
$this->set(compact('dealers'));
}
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash('Invalid Product', true));
$this->redirect(array('action'=>'index'));
}
if (!empty($this->data)) {
if ($this->Product->save($this->data)) {
$this->Session->setFlash('The Product has been saved', true));
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash('The Product could not be
saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->Product->read(null, $id);
}
$dealers = $this->Product->Dealer->generateList();
$this->set(compact('dealers'));
}
function delete($id = null) {
if (!$id) {
$this->Session->setFlash('Invalid id for Product', true));
$this->redirect(array('action'=>'index'));
}
if ($this->Product->del($id)) {
$this->Session->setFlash(__('Product deleted', true));
$this->redirect(array('action'=>'index'));
}
}
}
?>
|
This controller you generated using the Cake Console contains the same
basic functionality you got from scaffolding, but now you
can tweak it to fit your needs. Pretty slick. Ready to go again?
Baking your products
views
Now that you've baked the products controller, all Tor needs is some
product views. Bake will do those for you, too. Start as before on
your /webroot/app directory:
../cake/console/cake bake.
The initial Bake menu should look just like it did when you baked the
controller. This time, though, it's time to bake some views. Press
V to select views. You will get another list of possible
views to be baked. Products should still be No. 2 on the list.
Bake will ask if you want to create some scaffolded views (Yes) and if
you want to create views for admin routing (No). You can come back
later and play around with the different baking options.
Once you get past those two options, Bake should inform you that it's
created the views.
Figure 5. Bake informs you that it
has created the views
Exit the Cake Console, open the app/views/products/index.ctp view,
and take a look. It should look something like Listing 9.
Listing 9. The index
<div class="products">
<h2><?php __('Products');?></h2>
<p>
<?php
echo $paginator->counter(array(
'format' => __('Page %page% of %pages%, showing %current%
records out of %count% total, starting on record %start%, ending on %end%', true)
));
?></p>
<table cellpadding="0" cellspacing="0">
<tr>
<th><?php echo $paginator->sort('id');?></th>
<th><?php echo $paginator->sort('title');?></th>
<th><?php echo $paginator->sort('dealer_id');?></th>
<th><?php echo $paginator->sort('description');?></th>
<th class="actions"><?php __('Actions');?></th>
</tr>
<?php
$i = 0;
foreach ($products as $product):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
?>
<tr<?php echo $class;?>>
<td>
<?php echo $product['Product']['id'] ?>
</td>
<td>
<?php echo $product['Product']['title'] ?>
</td>
<td>
<?php echo $html->link(__($product['Dealer']
['title'], true), array('controller'=> 'dealers', '
action'=>'view', $product['Dealer']['id'])); ?>
</td>
<td>
<?php echo $product['Product']['description'] ?>
</td>
<td class="actions">
<?php echo $html->link(__('View', true),
array('action'=>'view', $product['Product']['id'])); ?>
<?php echo $html->link(__('Edit', true),
array('action'=>'edit', $product['Product']['id'])); ?>
<?php echo $html->link(__('Delete', true),
array('action'=>'delete', $product['Product']['id']),
null, sprintf(__('Are you sure you want to delete
#%s?', true),
$product['Product']['id'])); ?>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
<div class="paging">
<?php echo $paginator->prev('<< '.__('previous', true),
array(), null, array('class'=>'disabled'));?>
| <?php echo $paginator->numbers();?>
<?php echo $paginator->next(__('next', true).' >>',
array(), null, array('class'=>'disabled'));?>
</div>
<div class="actions">
<ul>
<li><?php echo $html->link(__('New Product', true),
array('action'=>'add')); ?></li>
<li><?php echo $html->link(__('List Dealers', true),
array('controller'=> 'dealers', 'action'=>'index'));
?> </li>
<li><?php echo $html->link(__('New Dealer', true),
array('controller'=> 'dealers', 'action'=>'add')); ?>
</li>
</ul>
</div>
|
Take a look in the those other views, as well. That's a whole lot of
writing you didn't have to do. You'll be tweaking these views later to
help lock down Tor.
Take it for a
test drive
You've baked a controller and the necessary views for the products
functionality. Take it for a spin. Start at
http://localhost/products and walk through
the various parts of the application. Add a product. Edit one. Delete
another. View a product. It should look exactly like it did when you
were using scaffolding.
Bake bigger and
better
This isn't the end of what Bake can do for you by a long-shot. There
will be a couple exercises at the end of the tutorial to let you
venture out on your own. Keep in mind that the code generated by Bake
is intended to be your starting point, not the end of your development
work. But it's a tremendous time-saver if used properly.
|  |