Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I just wanted some advice regarding the MVC way of doing things. I am using codeigniter and I was wondering if it's better to have one controller per page for a website or to have one controller for all the pages?

Let's say I have a simple website where you can visit the homepage, login, create an account and contact the admin.

  1. Would it be better to have these controllers: frontend(index), login, account, contact OR having one controller called frontend or whatever with the actions such login, createAccount, contact?

  2. When do you know if its better to use one controller in a situation?

share|improve this question
    
I've always lived by the creed: One Controller to Rule them all, and in the Darkness Bind them. (Not really, but I like the sound of it. :-) –  Peter Rowell Apr 25 '11 at 14:27
add comment

4 Answers

up vote 13 down vote accepted

It's better to have controller per logic unit, for example AccountController (login, registration), PagesController (home, contact), Backend -> PagesController (create, edit, delete), UsersController (create, edit, delete) and so.

share|improve this answer
    
How would you represent a website with theses areas : home, login, account, contact. Would you use 2 controllers like your example ? if you go to localhost/ it open the homecontroller then if you go localhost/contact in theory shouldnt it go to contact controller ? and what you mean by backend ? –  Rushino Apr 25 '11 at 14:18
    
It depends what is the structure of the pages and how many pages you have. I will make HomeController (home, contact) or PagesController (home, contact OR details(id)). For example in ASP.NET MVC you have default HomeController with Home and About page. –  Santas Apr 25 '11 at 14:24
    
I like this method. Also a ClientController(or whatever you want to call it) for Actions called via Jquery.Ajax which aren't specific to any particular part of your application. ie reusable from any of your views –  Chris Apr 25 '11 at 16:09
    
Seem the right answer to me. CodeIgniter accept sub directories for controllers which enable to seperate controllers into zones so i can end up with two pagescontroller (one per zone). Thanks! –  Rushino Apr 25 '11 at 17:44
add comment

@Rushino You have two 'apps' here - the front-end (for readers) and the backend (for admins). For every group of functionality, you have a controller.

Logging in is such a group, which includes the generation of the form HTML (the fields, calling the view), and the handling of the form (the validation, connecting with the model). So 'login' is a controller with two actions - generateForm and handleForm.

Pages is divided between the front end app - which just shows pages - and the backend app which allows editing, deleting, creating, and possibly views them in a different way. The homepage is 'just another page' on the front end at least, so fits within the pages controller. On the backend, its logic might be different enough that it justifies having a different controller entirely.

For users - if users can register themselves, they will need a frontend controller, but if not, everything to do with users just goes in the backend.

Note that each of the backend functions may require both a generator and a handler. These things can be split out into config files, though, with a plugin that is a generic form generator.

In summary, it looks like this:

Frontend
  Pages
    View, Handle
  Login
    View, Handle
  Users
    Register (note that the handler can be the same as 'create' on the backend)
  Contact
    View
    Handle

Backend
  Users
    Create, Delete, Edit, Update, View
  Pages
    Create, Delete, Edit, Update, View
share|improve this answer
    
Wait.. your saying that one section represent one apps ? interesting way of doing it (and probably THE way of doing it). Wonder if codeigniter do it this way.. will check. I must be sure that you can go from one app to another without breaking any session or connection state. –  Rushino Apr 25 '11 at 15:00
    
@Rushino CodeIgniter can do it this way - you can put folders inside the Controllers directory. The distinction between 'apps' isn't at the database/model level, but at the controller/view level. The reason for the separation is that your backend is doing very different things, often with a completely different design. It helps with security, because you can IP restrict the entire backend directory. And it helps with development because you can work on the backend without affecting the frontend. –  Blowski Apr 25 '11 at 15:04
add comment

I think you should use a Controller per business unit, like OrdersController for all operations related to orders and such. I am aware that in this case, Controllers get HUGE, but we can still use helper classes to delegate things like model initialization and partial classes to spread actions in separate files.

For example I can have OrdersControllerCreate.cs and OrdersControllerList.cs files for the OrdersController class each one with the corresponding set of Actions. Makes things much cleaner and still keeps orders operations centralized in a single controller class.

Just my 2 cents.

share|improve this answer
add comment

I think that you could take a different approach:

One main controller as a front door that delivers request to specific controllers. This way you could use this front controller to check common things like user authentication, google analitics, and any other general stuff you would like to do and keep the MVC structure pure.

This is not my idea but Symfony Framework works in this way so i can tell you that by my experience this is a really nice and elegant way to implement a frontend.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.