debuggable

 
Contact Us
 
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61

Dessert #8 - Render custom errors

Posted on 17/9/06 by Felix Geisendörfer

This is a very small but hopefully tasteful dessert. You've probably seen the /app/views/errors/ folder before and you maybe also know that you can use it to overwrite the default error templates which can be found in /cake/libs/view/templates/errors/ (error404.thtml, missing_action.thtml, missing_component_class.thtml, missing_component_file.thtml, missing_connection.thtml, missing_controller.thtml, missing_helper_class.thtml, missing_helper_file.thtml, missing_layout.thtml, missing_model.thtml, missing_scaffolddb.thtml, missing_table.thtml, missing_view.thtml, private_action.thtml, scaffold_error.thtml).

But what you might not know, or have not used before is that you can also use this folder to place your own error templates in it. For example if you have an action where the user needs to have a certain permission to do something and you want to render /app/views/errors/permission_denied.thtml when the permission isn't set, you can do it like that:

$this->viewPath = 'errors';
$this->render('permission_denied');

Now I've seen people using $this->render('../errors/permission_denied') before, but I think this is a more logical & cakish' way of doing it. It can also be used to render views from different controllers or elements, *but* I would not recommend you to do this unless you have a good reason to do so.

--Felix Geisendörfer aka the_undefined

 

Dessert #7 - Conventions over Ego

Posted on 16/9/06 by Felix Geisendörfer

Ok, this is probably one of the most important tips I'll give throughout this entire "desserts" series, so listen up.

For those of you who have been reading this blog for a while you probably know that I've written a lot about soft hacking CakePHP which allowed to overwrite some difficult-to-bypass conventions with custom behavior. But lately I have come to realize that I was all wrong about this kind of stuff. Not wrong in the sense that I published bad code, or had bad ideas, but I was wrong by misunderstanding the basic principles of RAD development.

Whenever I worked on an application with CakePHP in the past I frequently noticed some things were I thought "Hmm, would'nt it be nice if this [function, class, ...] would work like this". And a lot of times I took it as a personal challenge to find a way to cirvumvent the standard behavior without having to modify any core files. Up to now I've only failed at this one single time when trying to make some major changes to the behavior of the current ACL implementation. But other then that, one way or the other, I was able to put my own configuration over the CakePHP'ish convention. Now as I already said, I think most of the times those soft hacks "improved" the framework and would be nice to have in the core. However, what I didn't realize back then was that I was loosing the #1 major advantage of using the framework - Rapid Application Development. Because by implementing all those modifications, I spent a lot of time on configuration that slowed down my development process considerably. And not even that, now that I had a good amount of little tweaks and "improvments" in my application my debugging began to be more difficult since whenever I hit a bug, I had to check if one of my soft hacks broke something. No way to get support in #cakephp or somewhere else if your code doesn't behave the default way CakePHP behaves.

So, let me try to translate the paragraph above in a pragmatic workflow for you guys so that you don't have to go through the troubles I went through. First of all: I am not saying that you should never soft hack some CakePHP behavior. Sometimes you have to support legacy table names, legacy url's or other things. BUT - most of the times - you don't. If you feel like tweaking some convention ask yourself this question: "Is this change needed to satisfy a real world requirement, or is it my ego pushing for a more 'advanced & flexible' approach to the problem". I don't hesitate to admit that in the past it was mostly my ego that demanded those nifty little tweaks that would be so cool to have. But looking back at it I didn't take any real advantages of it. A while ago I read about about an extreme/agile programming approach called YAGNI (You Arent Gonna Need It), and I think my advice above is a very pragmatic adoption of it when working with a framework like CakePHP.

Today I have started to completly refactor my current project under the aspect of removing all tweaks I did to CakePHP behaviors and I noticed something else I didn't even percieve as soft hacks before: My AppController modifications. When looking at my old AppController I noticed that I filled it with nice and convenient functions I wanted to have available throughout my project. Now I don't say it is a bad practise to put useful stuff in your AppController, but I think there is a better one to do it. Instead of filling it with all those functions directly try to think if they could be refactored as Components. This maybe doesn't sound like a big difference, but I found that now that my AppController has less then 20 lines of code in it and my components folder has 3-4 more components, the structure and simplicity of my project has increased dramatically. I mean stuff like a beforeFilter that would send a Utf-8 header, retrieve my MenuEntries and a very simple Auth function seemed to work just fine in the AppController, but now that I've moved them into components my understanding for the application really increased. I can easily turn those things On & Off by removing the components and tracking down bugs became a lot easier.

So far so good, I would love to hear your guys oppinion about this post.

PS: Oh and if you are afraid I'll never publish a soft hack again, that's not going to happen either. But I'll try to be a lot more thoughtful about my reasons for doing so and will always point to this article when describing the technique I used ; ).

--Felix Geisendörfer aka the_undefined

 

Dessert #4 - Keep your Cake fresh (use SVN HEAD)

Posted on 15/9/06 by Felix Geisendörfer

This is something you might already have found your own solutions for, but never the less I think it's a topic people will struggle with when first using CakePHP together with SVN to version their project. However, you should already have an alright understanding for SVN itself to follow this post. If not, checkout this free svn book for information.

Ok, back to the topic. The problem is the following: You use CakePHP (or any foreign vendor, but let's keep it simple for now) to create your project and want to regulary update your version to enjoy the benifits of the frequent changes in the SVN trunk (like bug fixes, new features, etc.).

There are basically 3 options you can accomblish this:

#1 Overwriting your Project Frequently

This method might be the first one you consider, but believe me it's the worst of all. The idea is basically to frequently either export the latest SVN HEAD version from the CakePHP repository, or to visit CakePHP.org and grab the latest nightly build. Aferwards you take the new version of /cake, /index.php, /.htaccess, /VERSION.txt and use them to overwrite them with the existing ones in your working copy. Afterwards you do a commit and voilá you just updated your CakePHP version.

Pro's:

  • Easy to understand
  • If a CakePHP update breaks the application you can easily roll back

Cons's:

  • Manual update required
  • Get's hairy when you modified CakePHP core files in your working copy or when updating /app

#2 Use svn:externals

The next idea you might try is to use the svn:externals property to directly link /cake (and eventually the other 3 files in /) to the latest SVN Version. If you use TortoiseSVN (highly recommended for Windows users) this is simply a matter of right clicking the root folder of the working copy of your application's trunks and selecting properties. Then you select the Subversion tab, choose the svn:externals from the drop down on the bottom and enter "cake https://svn.cakephp.org/repo/branches/1.2.x.x/cake" in the text field below (assuming you are using CakePHP 1.2). Make sure you have deleted /cake in your working copy, then run svn update and SVN will automatically fetch the latest SVN version of the /cake folder and put it in your working copy. Whenever you run svn update from now on, you will also get the latest changes from the trunk. I think you could also link to the 3 other files in / with this method, but I haven't tried that so far.

Pro's:

  • Easy to setup
  • CakePHP Updates flow in almost automatically
  • Allows modification of CakePHP core files

Cons's:

  • Modifications to CakePHP core files will not be versioned (and therefor not be available to other people using the same repository)
  • If a CakePHP update breaks your application rolling those changes back get's a bit hairy
  • /app can (should) not be updated this way

#3 Use a vendor branch

Using a vendor branch is probably the most advanced of all approaches, but also the most complicated compared to the other ones. The idea is basically to create a branch for every vendor your project depends on (in our case CakePHP) and to regulary update this branch with the latest version of the vendor library. After updating the vendor branch you simply merge the changes between the previous vendor branch update and the current one into your trunk and only those changes will be applied to your application. To understand this proccess a little better I would recommend you to read this page about vendor branches I already mentioned.

Pro's:

  • CakePHP core files can be modifed and versioned
  • If a vendor update breaks the application you can easily roll back
  • You can easily recieve updates to /app

Cons's:

  • Difficult to set up
  • Manual update of the vendor branch required (but you could automate this)

Conclusion

There is not perfect way to handle this. When working on an application with a group of developers, using a vendor branch gives you most control about the entire proccess. Personally, when working on a project all by myself I often use method #2 since it's quite simple to setup and easy to maintain. The important thing is that you know about the existing options and their advantages / disadvantages so you can choose which one suits your project best. However, method #1 should be avoided if possible ; ).

Another hint: Right now most changes to CakePHP go into the 1.2.x branch and therefor the stuff above doesn't make a lot of sense if you are working with 1.1.x right now. Currently I'm working on the new ThinkingPHP.org and another project using the 1.2.x branch and it seems pretty stable, however it's not the officially recommended version right now, so I recommend you to only do this if you are pretty familiar with CakePHP and know what you are doing.

Oh and before I forget: You should almost never have to modify anything inside /cake. Often people who do that and post their own fixes on Trac are wrong, and their problems can be solved in /app. However, never say never, being able to modify core files is still a nice option to have, *especially* when using those technics above for including other vendors that don't write as perfect code as the CakePHP developers do ; ).

--Felix Geisendörfer aka the_undefined

 

Dessert #2 - Become friends with the Inflector

Posted on 14/9/06 by Felix Geisendörfer

It's still day one of my "10 Days of Free Dessert!" challenge, and here comes the 2nd post already (which doesn't count for tomorrow of course).

One of my favourite class in CakePHP is the Inflector. Whenever I work with file names it's very useful to convert them from lower_case_and_underscored into CamelCasedOnes. Doing this is very easy:

Inflector::camelize('my_file_name');

This would return MyFileName (even so the php docs in the class say "camelCased" which would make you think camelBack is being used, but it's really not).

Or yet another nifty trick you can use if you got a lot of similar Views, is to replace your Model name in them with a small piece of Inflector logic so you don't have to go through all of them and replace "Post" with "Item" and so on:

<h2>Create a new <?php echo Inflector::classify($this->name); ?></h2>

If your Controller is named Posts, this would output a 2nd level headline saying: "Create a new Post". Of course this only works if you stick with the convention of using pluralized Controller names and singularized Model ones, but you can see the advantage.

So if all of this sounds convenient to you, go ahead and checkout /cake/libs/inflector.php to find out about all the other great functions it contains!

--Felix Geisendörfer aka the_undefined

 

10 Days of free Dessert! (CakePHP Tips)

Posted on 13/9/06 by Felix Geisendörfer

If you have been following this blog since it's beginning in early January this year, you probably know that I was posting a lot more short and easy to adapt tips back then.These days I write a lot of lengthy and pretty specific articles that are not useful to quite everybody out there and sometimes take long to write.

For that reason I'm announcing the "10 Days of free Dessert!". This basically means that I'll post at least 1 useful and easy to adapt CakePHP tip begining tomorrow for the next 10 days. I will try to pick things you might not have heard before and that didn't get a lot of loving from the docs team so far ; ).



In case I break my promise and miss only 1 day of posting a new tip (my time zone is GMT+1), I'll take & post a picture of myself putting my face into a cake.

So this last part should make sure I'll stay with it, even so some of you might wouldn't mind if I miss day 10 ; ).

I hope you guys are going to enjoy it.

--Felix Geisendörfer aka the_undefined

 
53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61