Make your life easier with these five CakePHP Quicktips
Posted on 27/5/08 by Tim Koschützki
Hi guys,
here are five quick CakePHP tips you should consider when you want to make your life easier. Isn't clean code all we want?
1. The prd() convenience function
Do you often find yourself doing the following in your controller, models and views?
Why not wrap it up into a nice function that you can call just like pr() ?
Simple, yet effective! You can just drop that into your bootstrap.php and do this from now on:
One line less to type! I hear many people argueing that you should use debug(). Good call, but it does not provide a parameter that let's you exit out, so you would end up doing something similar anyway. If someone uses anything else, be sure to throw it into the discussion.
2. How to debug your CakePHP emails?
Yeah so you set up a local mailserver in order to test your emails' output? Then had to wait between one and twenty minutes for the email to arrive? That is not KISS is it?
Cake's Email Component has a nice debug mode which you can use. Just set the following in your controller:
The Component stores its debug output as a Session flash Message, however. In order to access the debug information, you would do this:
prd($this->Session->read('Message.email'));
The dump includes all headers, subject and message. The debug output is internally wrapped into a <pre> tag and therefore you have to keep in mind that non-explicit newlines will be shown as such in the debug output. However, they will not be in the email text. Be sure to explicitely insert newlines in the email via
for example.
You could also create a debugEmail() method in the app controller to wrap this Session read call to not always have to remember it.
3. Use elements where possible and make them belong to the controller
In a web application you will find yourself dealing with the same "site elements" time and again. Cake's elements are very handy for that. So why not use the views of a specific model as an element, too, to save code lines? Have a look at this in a fictive /views/posts/index.ctp
<p>Sorry, there are no posts yet!</p>
<?php return; endif; ?>
<?php foreach ($posts as $i => $post): ?>
// big long code to render the post which is duplicated in /views/posts/view.ctp
<?php endforeach; ?>
This looks much better:
<p>Sorry, there are no posts yet!</p>
<?php return; endif; ?>
<?php foreach ($posts as $i => $post): ?>
<?php echo $this->element('../posts/view', array('post' => $post, 'forIndex' => true, 'excerpt' => false)); ?>
<?php endforeach; ?>
You can use that as an element now in the index.ctp view as we did or as a different page. Only controller-independent elements should go into /views/elements. Everything else should stay in the controller-specific folder as view files. Disagree? Share your view!
4. Combine your h1 titles with Cake's page title
Very often people set the page title within their controller, which is bad. The page title is view logic so it should go into the view. For everybody not knowing about this yet, you can do the following in any view file as well:
So let's go a step further and output the page title as the h1 headline for your page in a very semantic line to kill two birds with one stone:
5. Avoid long parameter lists
A method with long parameter lists is always not a nice thing. It takes up space and will most likely need to be wrapped over two lines. How ugly!
Consider this:
$defaults = array(
'assocs' => array(
'types' => array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany')
),
'queries' => array(
'filters' => array(),
'associated' => true,
'describe' => false
),
'schema' => array(),
'log_sql_table' => 'logs'
);
$this->settings = am($defaults, $settings);
}
instead of a function with a long parameter list.
Happy baking!
-- Tim Koschuetzki aka DarkAngelBGE
You can skip to the end and add a comment.
die(pr($someVar))
Not completely sure I buy into #4, but I see where you are coming from, and I like the rest.
In a few situations I use the same view file for a couple of actions, and it is useful to change the pageTitle in the controller method to modify. It's really convenient to do it that way for those pages (add/edit methods using the same view for example). It seemed more elegant and easier to recognise for others in the future to do this via $this->pageTitle than a separate $this->set('title' ....) Perhaps it is not entirely MVC but I can let that one go.
For the add/edit example, to get around this it is possible to look at the action name and work that into the pageTitle anyway .... ( essentially do something like $this->pageTitle = $this->action . " Item" etc ... )
Thanks Tim, some excellent tips there, I will certainly be giving all these a try
@Peter: Cool, please let me know how it goes.
@Abhimanyu: Yeah we will do, for sure.
@Aitch: Why do you not buy into #4? Let's discuss it. The way your last paragraph describes is the approach I am choosing, too.
I'm confused about the elements. Where do we put the files for elements that belong to the controller?
Email hack is great ;-) thanks Tim
Thank you Tim! Though 5 may hurt semantics (documentation, IDE's etc)?
@Kvz: Do you have an example of how this could hurt?
@Khaled: Cheers
#5: it is one of my pet peeves if not documented carefully.
Cake uses a lot of associative arrays as parameters, but the documentation has not caught up with the code in places. And I find myself spending time looking at source code to find out what parameters the function accepts.
@Shane: Exactly you are right. That's why extra care is being taken for writing the cookbook now.
About #3:
What if I want to show only a small snippet of the post and not the same view that in posts/view. I think the scenario that you set is unusual, most of the times you just want to show a small snippet linking to the whole view action.
Martin Bavio: You would do it like this:
http://bin.cakephp.org/view/1074611387
Notice the excerpt variable being set to true. Then in the actual view.ctp you would do your TextHelper::truncate logic or whatever if that variable is true.
Does that answer your question?
Freaking magic! Tim, you are a genious, goodbye elements!
Number 4. actually hit me hard. I have been a bad puppy. Will do better in the future.
I actually had some sidebars (elements) used in layouts set from the controller too and used the same logic to move those to individual views.
Just thought about another email debugging method, prd() is not possible all the time.. why not create a temporary file in 'tmp' folder instead.
I found that with tip number one I also needed to implement a debug_backtrace (otherwise my debug info referrenced the bootstrap file rather than the place where I was calling my debug/die function):
function d($data)
{
$backtrace = debug_backtrace();
debug('File: ' . $backtrace[0]['file'] . ' Line: ' . $backtrace[0]['line']);
unset($backtrace);
die(debug($data));
}
Of course debug_backtrace is PHP5 specific.
debug_backtrace is not php5 specific as I previously mentioned. I was thinking of debug_print_backtrace.
debug_backtrace (PHP 4 >= 4.3.0, PHP 5)
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
Hey... nice tips. Especially the debug email. Keep posting these mini-tips as you find it, I really enjoy these quickies on my projects.