php Magento 中的自定义表单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1066127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:50:54  来源:igfitidea点击:

Custom forms in Magento

formsmagentocontrollerphp

提问by Dan

Can anyone provide a dummy guide \ code snippets on how to create a front end form in Magento that posts data to a controller action.

任何人都可以提供有关如何在 Magento 中创建将数据发布到控制器操作的前端表单的虚拟指南\代码片段。

Im trying to write a variant of the contact us from. (I know its easy to modify the contact us form, as outlined here). I'm trying to also create a feedback form with additional fields.

我正在尝试编写与我们联系的变体。(我知道它很容易修改与我们联系表单,如概述在这里)。我还尝试创建一个带有其他字段的反馈表单。

Given this basic form:

鉴于此基本形式:

<form action="<?php echo $this->getFormAction(); ?>" id="feedbackForm" method="post">   
                <div class="input-box">
                    <label for="name"><?php echo Mage::helper('contacts')->__('Name') ?> <span class="required">*</span></label><br />
                    <input name="name" id="name" title="<?php echo Mage::helper('contacts')->__('Name') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserName()) ?>" class="required-entry input-text" type="text" />
                </div>

    <div class="button-set">
        <p class="required"><?php echo Mage::helper('contacts')->__('* Required Fields') ?></p>
        <button class="form-button" type="submit"><span><?php echo Mage::helper('contacts')->__('Submit') ?></span></button>
    </div>
</form>

What are the basic step I need to take to get inputted name to a controller action for processing?

我需要采取哪些基本步骤才能将输入的名称输入到控制器操作以进行处理?

回答by Dan

If any one is interested, I solved this by building my own module which was heavily based on the Magento_Contactsmodule.

如果有人感兴趣,我通过构建自己的模块来解决这个问题,该模块在很大程度上基于该Magento_Contacts模块。

Here are some links that helped me figure things out.

以下是一些帮助我解决问题的链接。

http://www.magentocommerce.com/wiki/custom_module_with_custom_database_table

http://www.magentocommerce.com/wiki/custom_module_with_custom_database_table

http://inchoo.net/ecommerce/magento/magento-custom-emails/

http://inchoo.net/ecommerce/magento/magento-custom-emails/

回答by Fabian Schmengler

To make $this->getFormAction()return the URL to your custom controller, you have two options:

要将$this->getFormAction()URL 返回到您的自定义控制器,您有两个选择:

  1. call setFormAction()somewhere else on the block.
  2. use a custom block type that implements getFormAction().
  1. 调用setFormAction()块上的其他地方。
  2. 使用实现getFormAction().

(1) is what happens in Mage_Contacts_IndexController::indexAction(), but (2) is the cleaner approach and I'm going to explain it in detail:

(1) 是 中发生的事情Mage_Contacts_IndexController::indexAction(),但 (2) 是更简洁的方法,我将详细解释它:

Create a custom module

创建自定义模块

app/etc/modules/Stack_Form.xml:

app/etc/modules/Stack_Form.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Stack_Form>
            <active>true</active>
            <codePool>local</codePool>
        </Stack_Form>
    </modules>
</config>

app/code/local/Stack/Form/etc/config.xml:

app/code/local/Stack/Form/etc/config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Stack_Form>
            <version>0.1.0</version>
        </Stack_Form>
    </modules>
    <frontend>
        <routers>
            <stack_form>
                <use>standard</use>
                <args>
                    <module>Stack_Form</module>
                    <frontName>feedback</frontName>
                </args>
            </stack_form>
        </routers>
    </frontend>
    <global>
        <blocks>
            <stack_form>
                <class>Stack_Form_Block</class>
            </stack_form>
        </blocks>
    </global>
</config>

This configuration registers the stack_formblock alias for own blocks and the feedbackfront name for own controllers.

此配置注册stack_form自己模块的模块别名和feedback自己的控制器的前端名称。

Create custom block

创建自定义块

app/code/local/Stack/Form/Block/Form.php

app/code/local/Stack/Form/Block/Form.php

class Stack_Form_Block_Form extends Mage_Core_Block_Template
{
    public function getFormAction()
    {
        return $this->getUrl('stack_form/index/post`);
    }
}

Here we implemented getFormAction()to generate the URL for our custom controller (the result will be BASE_URL/feedback/index/post).

在这里,我们实现getFormAction()了为我们的自定义控制器生成 URL(结果将是BASE_URL/feedback/index/post)。

Create custom controller

创建自定义控制器

app/code/local/Stack/Form/controllers/IndexController.php

app/code/local/Stack/Form/controllers/IndexController.php

class Stack_Form_IndexController extends Mage_Contacts_IndexController
{
    public function postAction()
    {
        // your custom post action
    }
}

If the form should behave exactly like the contact form, just with a different email template and additional form fields, there are two solutions that I have outlined at https://magento.stackexchange.com/q/79602/243where only one of them actually requires a custom controller action to send the form:

如果表单的行为与联系表单完全一样,只是使用不同的电子邮件模板和其他表单字段,我在https://magento.stackexchange.com/q/79602/243中概述了两种解决方案,其中只有一种他们实际上需要一个自定义控制器操作来发送表单:

If you look at the contacts controllerused in the form action, you will find that

  1. the transactional template is taken directly from the configuration
  2. all POST data is passed to the template (as template variable data), so that you can add any additional fields to the form template and use them in the email template. But validation is hard coded for "name", "comment", "email" and "hideit".

So, if you need a completely different email template or additional/changed input validation, your best bet is to create a custom controller with a modified copy of the postActionof Mage_Contacts_IndexController.

But there is another solution that is a bit limited but without any custom code involved:

  • create a hidden input that determines the type of the form. It could be just <input type="hidden" name="custom" value="1" />.
  • in the contact transactional email template, use the ifdirective to show different content based on the form type:

    {{if data.custom}}
        ... custom contact form email ...
    {{else}}
        ... standard contact form email ...
    {{/if}}
    

如果查看 表单操作中使用的联系人控制器,您会发现

  1. 事务模板直接从配置中获取
  2. 所有 POST 数据都传递到模板(作为模板变量data),以便您可以向表单模板添加任何其他字段并在电子邮件模板中使用它们。但是验证是硬编码的“姓名”、“评论”、“电子邮件”和“隐藏”。

因此,如果您需要一个完全不同的电子邮件模板或附加/更改的输入验证,最好的办法是创建一个自定义控制器,其中postAction包含 Mage_Contacts_IndexController.

但是还有另一种解决方案有点受限但不涉及任何自定义代码:

  • 创建一个确定表单类型的隐藏输入。它可能只是<input type="hidden" name="custom" value="1" />.
  • 在联系交易电子邮件模板中,使用if指令根据表单类型显示不同的内容:

    {{if data.custom}}
        ... custom contact form email ...
    {{else}}
        ... standard contact form email ...
    {{/if}}
    

How to use this custom block

如何使用这个自定义块

You can add the form anywhere in the CMS using this code (CMS directive):

您可以使用以下代码(CMS 指令)在 CMS 中的任何位置添加表单:

{{block type="stack_form/form" template="path/to/your/form.phtml"}}

If you do this, you need to add "stack_form/form" to the block whitelist under System > Permissions > Blocks!

如果这样做,您需要将“stack_form/form”添加到System > Permissions > Blocks下的块白名单中!

Or in the layout using this code (layout XML):

或者在布局中使用此代码(布局 XML):

<block type="stack_form/form" name="any_unique_name" template="path/to/your/form.phtml" />

Solution without custom module

没有自定义模块的解决方案

If you use the solution without custom controller and a single email template mentioned above, you can set the form action using layout XML as well.

如果您使用没有自定义控制器和上述单个电子邮件模板的解决方案,您也可以使用布局 XML 设置表单操作。

To achieve this, we use the feature to call helpers as parameters for block actions. Unfortunately, the core helper does not have a public method to get a URL but the helper from Mage_XmlConnecthas, so you can use that one:

为了实现这一点,我们使用该功能来调用助手作为块操作的参数。不幸的是,核心助手没有获取 URL 的公共方法,但助手Mage_XmlConnect有,因此您可以使用该方法:

<block type="core/template" name="any_unique_name" template="path/to/your/form.phtml">
    <action method="setFormAction">
        <param helper="xmlconnect/getUrl">
            <route>contacts/index/post</route>
        </param>
    </action
</block>

In the CMS directive you cannot use helpers, so there you would need to put the actual URL:

在 CMS 指令中,您不能使用助手,因此您需要在其中放置实际的 URL:

{{block type="stack_form/form" template="path/to/your/form.phtml" form_action="/feedback/index/post"}}

Since you probably have different CMS pages/blocks in different store views, this should not be a big problem.

由于您可能在不同的商店视图中有不同的 CMS 页面/块,这应该不是什么大问题。