Zend_Form:addElementPrefixPath 与 addPrefixPath

发布于 2024-12-29 11:57:25 字数 3168 浏览 1 评论 0原文

我目前正在使用 Zend_Form 构建自己的一组表单元素,并希望自定义表单中的所有元素都能够使用我的自定义装饰器,

因此我创建了一个如下所示的自定义表单:

<?php
class Nuke_Form extends Zend_Form
{

    public function __construct($options = null)
    {
        $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        parent::__construct($options);

    }

}

为了完整起见,这是我的装饰器

<?php
class Nuke_Form_Decorator_TwitterBootstrap_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

以及我在控制器中创建的具体表单实现

class App_Form_Index_Test extends Nuke_Form
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Nuke_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

,但由于某种原因,元素无法找到装饰器并输出以下异常:

Message: Plugin by name 'ControlGroup' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/

分析异常,我看到我的插件路径未添加,即使我已明确添加它通过使用Nuke_Form 类中的 addElementPrefixPath()。


奇怪的是,当我将 PluginPath 单独添加到每个自定义元素时,它工作完美,如下所示。

<?php
class Nuke_Form_Element_Text extends Zend_Form_Element_Text
{
    public function init()
    {
        $this->addPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        $this->addDecorators(array(
            array('ViewHelper', array(
                'helper' => 'formText'
            )),
            array('Errors'),
            array('Description', array(
                'placement' => Zend_Form_Decorator_Abstract::APPEND,
                'class' => 'help-block'
            )),
            array(array('controls' => 'HtmlTag'), array(
                'tag'   => 'div',
                'class' => 'controls',
            )),
            array('Label', array(
                'class' => 'control-label',
                'requiredSuffix' => ' *',
                'placement' => Zend_Form_Decorator_Abstract::PREPEND
            )),
            array('ControlGroup')
        ));
    }
}

我正在使用最新版本的 Zend Framework (v1.11.11)。

经过一些研究,我注意到 addElementPrefixPath() 会在调用时添加所有添加的表单元素的路径,我认为这就是为什么在 Nuke_Form 构造函数中调用它时它不起作用,因为当时尚未添加任何元素。但是我们应该如何使用这个方法呢?我在网上找到了几个在构造函数中成功调用它的示例。我感到困惑或忽略了某些事情。

I'm currently building my own set of Form elements with Zend_Form and want all my elements in my custom form to be able to use my custom Decorators

So i've created a custom form like this:

<?php
class Nuke_Form extends Zend_Form
{

    public function __construct($options = null)
    {
        $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        parent::__construct($options);

    }

}

And for completeness sake, this is my Decorator

<?php
class Nuke_Form_Decorator_TwitterBootstrap_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

and the concrete form implementation I'm creating in my Controllers

class App_Form_Index_Test extends Nuke_Form
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Nuke_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

But for some reason the Elements fail to find the Decorators and output the following exception:

Message: Plugin by name 'ControlGroup' was not found in the registry; used paths: Zend_Form_Decorator_: Zend/Form/Decorator/

Analyzing the exception I see my plugin path isn't added, even though I've added it explicitly by using addElementPrefixPath() in the Nuke_Form class.


The strange thing is, when I'm adding the PluginPath to each of my Custom Elements individually, it works flawlessly, like below.

<?php
class Nuke_Form_Element_Text extends Zend_Form_Element_Text
{
    public function init()
    {
        $this->addPrefixPath('Nuke_Form_Decorator_TwitterBootstrap', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');

        $this->addDecorators(array(
            array('ViewHelper', array(
                'helper' => 'formText'
            )),
            array('Errors'),
            array('Description', array(
                'placement' => Zend_Form_Decorator_Abstract::APPEND,
                'class' => 'help-block'
            )),
            array(array('controls' => 'HtmlTag'), array(
                'tag'   => 'div',
                'class' => 'controls',
            )),
            array('Label', array(
                'class' => 'control-label',
                'requiredSuffix' => ' *',
                'placement' => Zend_Form_Decorator_Abstract::PREPEND
            )),
            array('ControlGroup')
        ));
    }
}

I'm using the latest version of Zend Framework (v1.11.11).

After some research i've noticed that addElementPrefixPath() will add the path to all added form elements when invoked, I think this is why it won't work when calling it in the Nuke_Form constructor since at that time no elements have been added yet. But how are we supposed to use this method then? I've found several examples online that do call it in the constructor with success. I'm puzzled or overlooking something.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧时模样 2025-01-05 11:57:25

尝试将其传递到构造函数中:
$options = array('elementPrefixPath' => 'Nuke/Form/Decorator/TwitterBootstrap/');

或者将其放入 init() 中:

public function __construct($options = null)
{
    parent::__construct($options);

}
public function init() {
    $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap_', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
}

}

我认为在 init() 中调用它效果最好。并且不必费心在这里调用 parent::init(); ,它只是 Zend_Form 中的一个空函数,无需重写。

这确实有效

我使用了除自定义元素之外的所有代码,我在 inti() 中设置了 elementPrefixPath 并使用 addDecorator() 针对普通 Zend_Form_Element 调用了 ControlGroup Decorator,这是输出:

<form enctype="application/x-www-form-urlencoded" class="form-horizontal" method="post" action=""><dl class="zend_form">
<div class="control-group"><dt id="username-label"><label for="username" class="required">Gebruikersnaam</label></dt>
<dd id="username-element">
<input type="text" name="username" id="username" value="" />
<p class="description">This is a description</p></dd></div>
<dt id="submit-label"> </dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit" /></dd></dl></form>

我所做的唯一更改是在前缀中添加尾随 _

<?php
class Application_Form_NukeForm extends Zend_Form
{

    public function __construct($options = null)
    {

        parent::__construct($options);

    }
    public function init(){
        $this->addElementPrefixPath('Jgs_Decorator_', '/Jgs/Decorator/', 'decorator');
    }

}

当然,我使用了自己的路径...

<?php
class Application_Form_Test extends Application_Form_NukeForm
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Zend_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int')
                ->addDecorator('ControlGroup');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

我只是重命名了装饰器以适合我的路径

<?php
class Jgs_Decorator_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

我认为你的问题在其他地方...
我还让 __constructor 工作,我必须调整参数才能获得正确的选项:

<?php

class Application_Form_NukeForm extends Zend_Form {

    public function __construct($options = array('elementPrefixPath' => array(
            'prefix' => 'Jgs_',
            'path' => '/Jgs/',
            'type' => 'decorator'
    ))) {

        parent::__construct($options);
    }

我真的希望这有帮助:)

try passing it in the constructor:
$options = array('elementPrefixPath' => 'Nuke/Form/Decorator/TwitterBootstrap/');

or maybe put it in init():

public function __construct($options = null)
{
    parent::__construct($options);

}
public function init() {
    $this->addElementPrefixPath('Nuke_Form_Decorator_TwitterBootstrap_', 'Nuke/Form/Decorator/TwitterBootstrap/', 'decorator');
}

}

I think calling it in init() will work best. And don't bother to call parent::init(); here, it's just an empty function in Zend_Form, nothing to override.

THIS DOES WORK

I used all of your code except the custom element, I set the elementPrefixPath in inti() and called ControlGroup Decorator using addDecorator() against a normal Zend_Form_Element, this is the output:

<form enctype="application/x-www-form-urlencoded" class="form-horizontal" method="post" action=""><dl class="zend_form">
<div class="control-group"><dt id="username-label"><label for="username" class="required">Gebruikersnaam</label></dt>
<dd id="username-element">
<input type="text" name="username" id="username" value="" />
<p class="description">This is a description</p></dd></div>
<dt id="submit-label"> </dt><dd id="submit-element">
<input type="submit" name="submit" id="submit" value="submit" /></dd></dl></form>

the only change I made was to add a trailing _ to the prefix.

<?php
class Application_Form_NukeForm extends Zend_Form
{

    public function __construct($options = null)
    {

        parent::__construct($options);

    }
    public function init(){
        $this->addElementPrefixPath('Jgs_Decorator_', '/Jgs/Decorator/', 'decorator');
    }

}

of course I used my own path...

<?php
class Application_Form_Test extends Application_Form_NukeForm
{
    public function init()
    {
        parent::init();

        $this->addAttribs(array('class' => 'form-horizontal'));

        $username = new Zend_Form_Element_Text('username');
        $username->setLabel("Gebruikersnaam")
                 ->setDescription("This is a description")
                 ->setRequired(true)
                 ->addValidator('NotEmpty', true)
                 ->addValidator('int')
                ->addDecorator('ControlGroup');

        $submit = new Zend_Form_Element_Submit('submit');

        $this->addElements(array($username, $submit));
    }
}

I only renamed the decorator to fit my path

<?php
class Jgs_Decorator_ControlGroup extends Zend_Form_Decorator_Abstract
{

    public function render($content)
    {
        $class = $this->getOption('class') ?: "control-group";

        $element = $this->getElement();
        $errors = $element->getMessages();
        if (!empty($errors)) {
            $class .= " error";
        }

        $output = '<div class="' . $class . '">' . $content . '</div>';

        return $output;
    }

}

I think your problem is somewhere else...
I also got the __constructor to work, I had to adjust the parameters to get the correct options:

<?php

class Application_Form_NukeForm extends Zend_Form {

    public function __construct($options = array('elementPrefixPath' => array(
            'prefix' => 'Jgs_',
            'path' => '/Jgs/',
            'type' => 'decorator'
    ))) {

        parent::__construct($options);
    }

I really hope this helps :)

起风了 2025-01-05 11:57:25

class Nuke_Form_Element_Text 中,如果调用 setDecorators() 而不是 addDecorators() 可能会更好,因为看起来好像要替换所有默认装饰器。
您也可以只添加 <代码>$this->loadDefaultDecoratorsIsDisabled();

in class Nuke_Form_Element_Text you might be better off if you called setDecorators() instead of addDecorators(), as it appears as though you are replacing all of the default decorators.
You could also just add $this->loadDefaultDecoratorsIsDisabled();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文