【问题标题】:Extending Blade in Laravel - Creating a custom form object在 Laravel 中扩展 Blade - 创建自定义表单对象
【发布时间】:2015-08-25 22:35:21
【问题描述】:

documentation on extending blade in Laravel 5 似乎没有太多深度,我很难理解我想做的事情是否可行。

注意:我使用的是 Laravel 5.1

这是 Laravel 文档给出的扩展刀片的唯一示例。

Blade::directive('datetime', function($expression) {
    return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});

现在我想做的是有一个如下所示的刀片文件:

@form('horizontal')
    {{ $form->text('email') }}
    {{ $form->text('password') }}
    {{ $form->submit }}
@endform

然后我希望在我使用@form 时创建一个新的 $form 对象,并在我使用@form 后使其可用,但在@endform 之后它不需要可用

经过一番谷歌搜索和闲逛后,我发现我可以做这样的事情:

\Blade::directive('form', function($expression) {
    return '<?php $form = new App\Form'.$expression.'; ?>
    <?php echo $form->open(); ?>';
});

(这是从以前的编辑更新的)

这就是大部分的方式。我有一个 $form 对象,可以创建一个新表单,我可以向该表单对象发送一个自定义参数。我也可以在@form 之后使用$form 对象。当然,它将在整个视图中可用,这并不完美,但不一定是问题。

但是,由于我似乎在做一些完全没有记录的事情,我担心我可能做错了什么,或者我以后可能会遇到问题。

我还应该注意,我在网上找到的每一个指南都提到了 $compiler->createMatcher 和 $compiler->createPlainMatcher,但这两个似乎在 Laravel 5.1 中都被删除了。

谁能提供有关刀片扩展如何工作的任何见解并提出更好的方法?现在它似乎可以正常工作,但感觉非常“hacky”,并且可能不安全地依靠前进。

更新 HTML 宏

根据以下建议 HTML 宏的答案更新此用例。 CSS Framework Bootstrap 包括垂直和水平表单的不同格式。此功能的目的是方便在这两者之间进行切换,示例如下:

@form('horizontal')
    {{ $form->text("email", $user->email, 'Email') }}
@endform

Form 类可能看起来像这样:

class Form
{
    public $direction;

    public function __construct($direction)
    {
        $this->direction = $direction;
    }

    public function text($name, $value, $label)
    {
        return $this->wrap('<input type="text" value="'.$value.'" />', $name, $label);
    }

    public function wrap($element, $name, $label)
    {
        if($this->direction == 'horizontal') {
            //Horizontal
            return '<div class="form-group">
                <label class="col-sm-2 control-label" for="'.$name.'">'.$label.'</label>
                <div class="col-sm-10">
                    '.$element.'
                </div>
            </div>';
        } else {
            //Vertical
            return '<div class="form-group">
                <label for="'.$name.'">'.$label.'</label>
                '.$element.'
            </div>';
        }
    }
}

据我所知,HTML 宏无法实现这种功能。

这都是伪示例代码,如有错误请见谅。我相信它的基本前提应该很清楚。

【问题讨论】:

  • 您可以扩展 FormBuilder 类并相当容易地实现此功能,而无需接触 Blade。看看Form::model() 以及它如何保存模型的状态。您可以创建自己的打开方法,或者使用另一个参数扩展现有方法,并在以后使用单个方法时使用它。
  • @Cryode 我之前没有听说过 Form::model() 方法,所以将研究它是如何工作的。

标签: laravel laravel-5 blade


【解决方案1】:

你可能想看看这个插件"illuminate/html": "~5.0"

你可以做这两种方法都会做的事情,比如打开表单。

{!! Form::open() !!}

{!! Form::model($pose,['method' => 'PATCH', 'route' => ['poses.update', $pose->id]]) !!}

作为奖励,您还可以获得许多其他物品。

{!! Form::text('title', null, [
           'class' => 'form-control', 
           'id' => 'title', 'placeholder' => 'Add title.'
          ]) !!}
{!! Form::textarea('body', null, [
           'class' => 'form-control', 
           'id' => 'body', 'placeholder' => 'Post a status'
          ]) !!}
{!! Form::close() !!}

还有很多其他人,see the source

就您的原始问题而言,您始终可以使用 5.0 功能,只需将原始方法 createOpenMatcher 放在您的服务提供商中即可。 See my answer here.

public function createOpenMatcher($function){
    return '/(?<!\w)(\s*)@'.$function.'\(\s*(.*)\)/';
}

每条评论更新

因此,根据您的评论,Illuminate 表单助手会按照您的要求进行操作。

{{ Form::open(['class' => 'form-horizontal']) }}

呈现为

<form method="POST" 
    action="http://example.com/sample" 
    accept-charset="UTF-8" 
    class="form-horizontal">
<input name="_token" 
    type="hidden" 
    value="ZqVwyZXXkh6sHLKpDJjvAJP0s6Bg5bXeuA1RcOnK">

任何传递给数组的东西都会被添加到表单标签中。

我可能无法 100% 理解您的问题,但我认为您可能正在尝试使用 Blade 扩展解决一些问题,而使用您的代码编辑器或 Form helper 插件可能更容易解决。也许您可以添加您尝试生成的两种类型的 HTML,我们可以讨论一下?

我同时使用PhPStormSublime text。这两个都有选项,您可以在其中包含文本的代码 sn-ps。在 PhPStorm 中,它们被称为 Live Templates,Sublime 将它们称为 snippets

我在我的文本字段中使用了一个 textfieldtab PhPStorm 实时模板。

<!-- $VALUE$ Field -->
<div class="form-group">
    {!! Form::label('$NAME$', '$VALUE$:') !!}
    {!! Form::text('$NAME$', null, [
               'class' => 'form-control', 
               'id'=>'$NAME$', 
               'placeholder' => '$VALUE$'
     ]) !!}
    {!! $errors->first('$NAME$', '<span class="error">:message</span>') !!}
</div>

它为您提供渲染 html

<div class="form-group">
        <label for="sample">Sample:</label>
        <input class="form-control" 
               id="sample" 
               placeholder="Sample" 
               name="sample" 
               type="text">
 </div>

虽然我不时扩展 Blade。我发现大多数时候,当我想扩展它时,通常有更简单的方法。

最终编辑

为什么不使用 CSS?

<style>
    form.horizontal .col-sm-10, form.horizontal .col-sm-2{
        display:inline-block;
    }
</style>

<form class="horizontal">
    <div class="form-group">
        <label class="col-sm-2 control-label" for="field_name">Enter Name:</label>
        <div class="col-sm-10">
            <input type="text" value="New Name" />
        </div>
    </div>
</form>
<form class="vertical">
    <div class="form-group">
        <label class="col-sm-2 control-label" for="field_name">Enter Name:</label>
        <div class="col-sm-10">
            <input type="text" value="New Name" />
        </div>
    </div>
</form>

【讨论】:

  • 请查看我的问题的更新。它对我正在考虑的这个特定用例没有帮助,我可以根据发送到 Form 类的 __construct 方法的内容来修改每个方法。
  • 感谢您的更新,但我仍然认为它有点错过了重点。示例 HTML 在我的问题中的 Form 类中。
  • @robjbrain 好的,所以我认为你想多了。我更新了我的答案以使用 CSS。它似乎尽可能简单!祝你好运。
【解决方案2】:

Laravel 有一个从核心框架中提取出来的 Forms 包。它可以在这里找到 - http://laravelcollective.com/docs/5.0/html

恕我直言,扩展 Blade 并不是实现您想要的最佳方式。您可以使用上述软件包中的自定义宏。例如,

Form::macro('horizontal', function()
{
    $form = '<input type="text" name="email">';
    $form .= '<input type="password" name="password">';
    $form .= '<input type="submit" value="Submit">';
    return $form;
});

在你看来:{!! Form::horizontal() !!}

编辑:对以下更新问题的回复

您可以扩展 FormBuilder 类以添加您自己的自定义方法 - https://github.com/LaravelCollective/html/blob/5.0/src/FormBuilder.php

添加一个私有的wrap 方法来接受输入和方向。或者你甚至可以有单独的 wrapHorizontalwrapVertical 方法。

【讨论】:

  • 嗯,我不确定这是否能达到同样的效果。用例(在这种情况下)将针对 Bootstrap 水平和垂直形式使用不同的标记。我将扩展我的问题以引用此问题。如果这可以通过宏来完成,我会印象深刻,但我不认为它可以。
  • 谢谢,我会考虑扩展 formBuilder 类,一旦我尝试了一些东西就更新
【解决方案3】:

试试下面的链接,你会发现它很有用。 http://laravel-recipes.com/categories/21

这里的表格格式为{{ ..Code goes here.. }}。在 laravel 5.1 中使用这些表单语法为{!! ..Code goes here.. !!}

【讨论】:

    猜你喜欢
    • 2018-05-14
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 2016-07-03
    • 2019-04-08
    • 1970-01-01
    相关资源
    最近更新 更多