Am I right in thinking that in Zend Framework, if I plan to have 5 pages at my site, I'd generally need 5 controllers? Do ZF developers typically create 1 controller per page ("page" as abtract app unit)?
The reason I am asking this is that previously for some reason I stuffed a lot of various actions into controllers so that they played role of pages, e.g. index/add, index/view, index/delete and displayed various small screens, e.g. small CRUD screens as opposed to grids displayed by index action.
But as of now I want to check my new understanding that actions are needed mostly for model updates and actions should, once run, immediately redirect back to controller/index. So it seems that views should mostly be used in index actions, and less frequently in other actions.
Does this sound architecturally valid?
I suppose thats one way of doing it... Using your analogy i suppose i use a controller like a "section" and actions like "pages" to those sections.
But thats getting stuck more on the old procedural||static paradigm of pages because really the action controller itself has no more to do with a page or section than the association you make as a developer. Ie. each page can potentially be a composite of numerous actions and views depening on the application's architecture.
For example if i have a blog modules i might have the following:
Controllers:
PostController
CommentController
Views:
post
display (display a single post)
list (list posts)
edit (create/edit post)
comment
display (display n comments)
list (list comments)
edit (create/edit/moderate comment)
embed-list (for use on the Post itself assuming this differs from display)
In my opinion, a controller should always group multiple methods that have a common use case. Try to find "nouns", that describe the functionality of your app: those are the controllers (while verbs are the controller methods).
If you have (for example) a blog, you may have:
ArticleListController (listing all
articles, listing the top 10, listing
all articles for a tag,...)
SingleArticleController (displaying one article, adding comments,...)
AdminController (lets you write Articles)
If you have just 5 pages (e.g. home, about, contact,...) the MVC architecture might not be the right fit.
indexAction is merely the default action for a given controller, useful for displaying a default view (the same as displaying the index.html or index.php page for a sub-directory).
It is completely acceptable to create a variety of actions on a per controller basis that may or may not each have their own views (i.e. add and edit). The controller is intended to group similar actions.
For example usage please refer to the documentation on Zend_Controller_Action. You may also find it useful to familiarize yourself with the workflow of Zend_Controller.
Related
In my previous company which had an all-ajax web ap, there was a from-scratch framework being used. The way page sections refreshed was that you'd call the controller with a string, and the controller would load one or more view files. The view file would almost always call a class or classes in the model. This was as it was when I got there.
I am now working with a new company to develop a new system and looking at framework candidate. A 30 minute tutorial on codeigniter shows the controller calling the model, and the model loading the view.
This is opposite to what I am used to from my experience, so I wanted to ask which strategy is more common. In my mind it seems more rational that the view is a "shell" or structure but which is restricted to needing the model to get to the business rules.
I'm not sure if I should share a link here, I am NOT trying to promote codeigniter, but the tutorial is located at https://www.youtube.com/watch?v=47VOtKiw9AQ at about 10:00. Thanks
tutorials. there are a lot of them.
controller calls the model and passes data to the view. thats the standard answer. however i'm now leaning towards - the controller assigns specific views, and then calls a template, passing $data.
and then in the template -- there are calls to a model to create the navigation bars for that template, and optionally a page display model.
otherwise -- either you have my_controller which everything passes through that could have calls to page display, navigation, etc.
Or you have to put page display details in every single controller. personally i'm not a big fan of the my_controller design pattern, and calls to a navbar in complex controllers are not optimal.
so in that case what might be considered a view -- a simple template file -- would be calling a model. but in this case its not really a "view" because its not displaying anything directly -- the template is calling the nav view, the header, the footer view, etc etc -- and then the actual page content is assigned by the controller.
this also gives you more portability - when you need to change details about the page display or navigation you only have to go to one place.
finally there's many php frameworks and many opinions. after a long dormant period the codeigniter framework is under active development. however if you are starting from square one take a look at Node as well, it has some compelling features depending on your use case.
I'm using CakePHP 2.2.3 and I need to build an admin/dashboard area for my site.
I have many models and controllers related to this models and in the dashboard I need to have the ability to CRUD all posts/users/news etc.
Obviously I need to build a Dashboard controller with some index action which will be show dashboard "home" page.
My question is: where to put all other actions – for posts/users/other things adding/editing ?
Should I put all this actions in this new dashboard controller or it's better to put this actions to related controllers(Posts/Users..)?
Keep your specific actions in each of their own controllers. A DashbaordsController is fine for whatever pages need to display a lot of different model information, but CRUD actions should be kept in their own Controller.
If you want/need a single page to be able to actually do the CRUD actions ON that page, you can use ajax and STILL call the actions of that specific Controller.
Bottom line, if you try to put all your CRUD into a single Controller, it's just going to get messy, and will be very confusing for future programmers (which includes yourself 6 mo from now).
It's so easy to include data from other Models $this->loadModel('MyModel');, that doing CRUD actions in their own respective Controller is not much of a hindrance. Again - the DashboardsController is still fine for those few pages that really are like dashboards, and have no alliance toward a specific model. But not for each model's CRUD.
Generally the ideal way is to do skinny controllers and keep logic as far down the stack as possible that is near to the models. Ideally you'd want to introduce libraries for code reuse and testing. Robert Martin aka Uncle Bob says that the web delivery and databases should be as much of a plugin as possible. This lets you unit test much better. As far as your particular case i'd want to keep it close to REST as i can so separate controllers ideally delegating to some lower level stuff.
I am not too technical but wanted to know since my tech team is implementing this way:
Do we need to create a 'controller' file for each set of views that we need to call on the website OR can we control ALL the views from 1 controller? It seems like more work to have multiple controllers control all the views. I would like to have 1 controller call all the views to cut down on project time but not sure if this is possible or even a good practice?
This is neither good nor bad practice. All that matters is that your code is clear and well structured. After that, Code Igniter gives you lots of flexibility on how you use controllers and views. Personally, I tend to use one view per action (so a controller often controls several views).
Yes, it's possibile; you can easily test it yourself:
class Customcontroller extends CI_Controller {
function index()
{
$data['test'] = 'test';
$this->load->view('header', $data);
$this->load->view('body');
$this->load->view('footer');
}
}
You'll notice that doing this way $data will be available to all views, even if not passed individually while loaded.
I find it a nice way to building pages, using views as blocks. So, you can also present views according to some constraints:
$this->load->view('header');
if($this->form_validation->run() == FALSE)
{
$this->load->view('display_form');
}
else
{
$this->load->view('form_sent');
}
$this->load->view('footer');
for example.
Although MVC stands for Model-View-Controller, and suggest a one-to-one correlation, using different views for a same controller I doubt it can be considered "bad practice"; as already being said, there's no really an ideal way of doing this, what's important is keeping the logic separated and making your code well-structured and organized, especially when working in a team.
It really depends on what your controller is supposed to do. If all you want to do is show blog posts or content pages, for example, you can just use one controller called 'blog' or 'pages'. Controllers handle the logic. If you have many features you'd like to run (such as accounts, events, photos, etc.) it's usually always wise to give each their own controller so they can handle operations suitably with their model.
If you use frameworks like CodeIgniter, you can use their routes feature to automatically route certain URLs through a particular controller. For example, if you wanted pages to have a URL of http://example.com/page/page-title - you'd need to use this line in your routes config file:
$route['page/(:any)'] = 'page/get_page';
Any URI request that contains 'page' will be handled by the 'page' controller and the 'get_page' method. You can they grab the page-title or page-id by using $this->uri->segment(2).
I will have a single controller using multiple views. Here is how. My webpages have common header, footer and navigational structure, so these views will be common to all the web page calls hence a controller may inherit a method that takes content and assembles a page using header/footer/common views. For displaying grids I may have a common grid view that I can keep using in multiple controllers for displaying tabular data. Different use cases can reuse some views. So it makes sense that you can use multiple views within one controller.
codeigniter itself does not restrict you on how many controllers you use.
but as a basic idea, i tend to seperate controllers into modules.
for example, if your site have a front end and a back end, i would separate them, so i got 2 controllers (each with their own views).
this way, if you have more than 1 person working on the site, you can assign 1 person with the front end, and the other with the back end.
further more, you can break them apart into smaller modules. for example, in the front end, there is a home page and an article page (certainly you have different views for those), you can also break them down if you feel they are complex enough. but if you think they are simple, then it is fine if you use 1 controller for those views.
I use php and usually structure my application into model-view-controller so its always accessed via index.php with class and method attributes. Class attribute passed as part of URL specifies controller class and method simply method to be called. This seems to be pretty common, but then I'm always having trouble in figuring out what controllers shall I create. What is the best, easiest and most applicable way to decide on what controllers should be created? I understand it depends on web application itself but must be some general way of thinking to get this process started.
I've found that building controllers based on your application's objects works well, and can take care of most actions you'll want for your app.
Take a look at SO -- there's URLs starting with /questions, /tags, /users, etc. I'd suggest a design which starts by creating a different controller for each object. /questions (or /questions/list) returns a list of all the questions. /questions/[0-9]+ returns the details of a particular question with that id number. /questions/ask returns the Ask Question interface.
As you continue building your app, you might find that the controller-based-on-objects method doesn't meet all your needs. For example, on my site (http://www.wysiap.com), I eventually made a /list controller to simplify my Grails URL mapping. But in most cases I did use this method and it's easy to figure out which controller should be doing different actions.
I recommend to think about the pages you'll need in your applications to accomplish all the requested tasks. You'll group similar tasks on the same page and create as many pages as you need. A page can be sliced in different views for specific actions.
With this in mind you could have one controller per page. Each view of the page can have its own method (action) in the controller. And inside the method of each view you can have a switch() that will enable you to have several tasks for the view. Example:
index.php (Dashboard controller)
/question-list (QuestionList controller, action index, display the whole page)
/question-list/add (QuestionList controller, action add, manage the "add" view with tasks like show-form, validate-form, insert-question)
/profile (Profile controller, action index)
/profile/edit (Profile controller, action edit, manage all the tasks requested for your profile)
...
I design most of my web applications this way and using Zend-Framework
I'm wanting to be sure that I am setting things up correctly. On a typical website with 10 pages, would each page have it's own controller with it's own IndexAction and it's own View folder with it's own index.phtml as a view?
Or do you have one controller with multiple Page1Action, Page2Action, etc and have multiple differently named view.phtml pages within view/index folder?
I'm leaning toward the former because then I can have a cleaner controller for each page...
Is there a standard, or is it subjective?
Your sitemap would play a major role in this question. But, in lieu of that, here's a few examples.
Example 1. Flat
/foo
/bar
/baz
You'll probably want to use separate controllers: Foo/IndexController.php, Bar/IndexController.php, and Baz/IndexController.php with each having an indexAction() method to pass information to your view (once again separate).
Example 2. A Little Bit Lower Now
/foo/bar
/baz
You'll only need two controllers: Foo/BarController and Baz/IndexController. If /foo needs a landing page you'll have to throw in a Foo/IndexController.php to be safe. Your actions are still indexAction(). Because you've not gone deep enough to hit that third level, your views are still index.phtml.
Example 3. Straight Line
/foo/bar/baz
You're down to onc controller: Foo/BarController.php. If you need landing pages for /foo and /foo/bar you'll need another controller for /foo (Foo/IndexController) and an indexAction() for both. With /foo/bar/baz you're actually down to a slightly different action now too - bazAction() (inside Foo/BarController.php). Your view is now baz.phtml.
Summary.
The wider the sitemap the more controllers you have and fewer actions. The more narrow the sitemap the fewer the controllers and more actions.
Postscript.
I should also state, this is also contingent on using default routing patterns. If you do something a little more sophisticated in routing patterns, this is all shot out the window. Sometimes we use routes to keep the number of classes manageable. When we have a wide sitemap it's possible to create some custom routes and use __call() within a controller to hand-off view data appropriately. Just another way to skin this cat.
Typically you would create one Controller for a related group of Actions. What related means is subjective.
Very roughly speaking, a group of related Actions operates on the same Model. At least that's a good starting point, but it rarely works out that simply, because few real-world applications consist solely of CRUD operations on each Model.
If you decouple the Model from being simply a data access component, you can more sensibly define a logical grouping of Controller Actions for a Model. A Model is where the majority of your code exists for business logic. Database persistence is just an (optional) internal detail of the Model, to preserve state from request to request. But a Model doesn't necessarily use a database. It could be standalone, or it could be an aggregation of other Model objects.
By default, each Action has its own View script. But this is also just a starting point, because you could use Layouts to make many View scripts share some if their markup in common, and you could use View Helpers and Partials and so on.