Best way to handle forms in blocks?
I'm coming from different MVC frameworks (eg Symfony) to Magento. I read a lot about Magento best practices and I can see Magento doesn't use the typical MVC style. Alan Storm wrote the followings:
it's not the responsibility of the controller to set variables for the view [...] controller's job is to do certain things to Models, and then tell the system it's layout rendering time.
I think I understand this approach as this can provide a kind of flexibility for blocks.
Right. But what about forms?
In a typical MVC framework you will get the request parameters in the controller, validate form data in the controller, make model operations (save, load, etc) or redirections if necessary there, and when everything is clean and tidy, you will provide the freshly baked output pieces for the view.
In Magento these all should happen inside a block and the (thin) controller is only supposed to prepare the layout and then render it. (If I understand.)
I tried to find an article (manual, forum topic, anything), which describes a creation steps of a separate module with an own new model, which can be editable via a form in the frontend by the user. I would like to see how a custom form should work in the frontend. I've found only general articles about blocks, forms, modifying or creating adminhtml forms or customising contact or newsletter signup forms.
I made it. It works now, but I'm not satisfied. So then, I checked the source code of the Contact form in the core module, and those messed up the entire picture for me. The built-in Contact form uses the IndexController to most of the above mentioned operations, (almost) like a standard MVC.
Could anyone suggest to me a best practice, how to manage a simple flow like the following? (I've got a solution for these below, but I'm not sure, is that the "right Magento way"):
My confusion is mainly around:
You can just look into the Customer/AccountController and see how the loginPost
, createPost
methods are handling the incoming form data.
I would never add the CRUD
logic to the block. You need to validate and process your POST data in your Controller. Block should contain only view-related logic: like format url, or prepare Collection
.
Also the form preparation lays on Controllers shoulders as well. You need to load your object and validate it inside the Controller action. Then there are few ways to pass it to the block:
Mage::register
(Registry) $this->getLayout->getBlock('your_form_block')->setEntity($object)
(directly set variable to block) Any redirection should be done in Controller only.
UPDATE Few words about why load model inside the controller.
loadLayout
and create all Blocks. You don't want to make user wait for all that time just to redirect him afterwards. Also you've forgotten about one more valuable part. If the validation fails inside your controller, you need to fill the form with the values User has sent. In Zend_Form that is done pretty, but with Magento forms you'll need to use session (like it's done in AccountController) - save all key-value parts in session and then in block check for those session variables existence. Again, you should do this only if your POST validation has failed and you're redirecting user back to your form. In successful case clear the session variables connected to the form.
As a general piece of advice: if you want to follow Magento style, read less forums and more core code.
I'm not a magento pro either, but I think I can answer your questions:
Where should I get and manage the request parameter? (I did it in the block class file) Depens on where you need them. If you are planning on saving them in a model, use the controller. If you want to ouput them on a page, use a block. Most cases you want to use the controller for this.
And load an object from the DB, based on it? (Also, and then passed to the phtml) If you want to pass a model to a template you should write a function on your block that gets the model.
How to pass it to the view, if I wouldn't load it there? (I would know a way, but I don't know the best way.) As stated above, make a block with a function that gets the model. Then from your template you can use $model = $this->functionThatGetsTheModel(); to reach this function and get the block.
Where should be the (POST) form data processed, validated and stored? (Block?) Things like saving models is controller stuff.
How can I use properly redirections in a block? Do I need redirection, as the thank you page should be a different block / page? Or just an alternativ (conditional) look of the same block? Its best to do redirects in your controller. And it's also best to make a new block/template for every page you are planning to make.
About the block/template topic: Read this page for more info about the usage of layout xml to use blocks and template http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-4-magento-layouts-blocks-and-templates
I hope this helps you get started with magento!
链接地址: http://www.djcxy.com/p/59480.html上一篇: Magento布局xml文件中的动作方法是如何使用的
下一篇: 最好的方式来处理块的形式?