laravel - 在 Laravel 中扩展 Blade - 创建自定义表单对象

标签 laravel laravel-5 laravel-blade

documentation on extending blade in Laravel 5似乎没有太多深度,我正在努力理解我想做的事情是否可能。

注意:我使用的是 Laravel 5.1

这是 Laravel 文档给出的唯一用于扩展 Blade 的示例。

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

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

@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 对象。当然,它会在整个 View 中可用,这并不完美,但不一定是问题。

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

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

任何人都可以深入了解 Blade 扩展的工作原理并提出更好的方法吗?目前看来它几乎可以工作,但感觉非常“hacky”,并且可能不安全地依赖于 future 。

更新 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 宏无法实现此类事情。

这都是伪示例代码,因此对任何错误表示歉意。我相信它的基本前提应该很清楚。

最佳答案

您可能想研究一下这个插件 "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 扩展来解决一些问题,而使用代码编辑器或表单帮助器插件可能更容易解决这些问题。也许您可以添加您尝试生成的两种类型的 HTML,我们可以讨论一下?

我同时使用 PhPStormSublime text 。这两个选项都有可以包含文本代码片段的选项。在 PhPStorm 中它们被称为 Live Templates Sublime 称它们为 snippets .

我使用 PhPStorm 的 textfieldtab 实时模板作为我的文本字段。

<!-- $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>

关于laravel - 在 Laravel 中扩展 Blade - 创建自定义表单对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30760336/

相关文章:

laravel - multiarch-support :amd64 : Depends: libc6:amd64 (>= 2. 3.6-2) 但它不可安装

php - 在 laravel eloquent 中处理映射表

php - 如何在laravel 5.2中为连接表执行sql计数功能

laravel - anchor 标记在 Laravel 5.2 上不起作用

php - Blade 模板布局结构

javascript - 将数据从 Laravel $collection 传递到 jquery 循环

laravel - Laravel 8 共享主机中缺少混合 list 文件

laravel - 将 css/js 文件从一个组件推送到另一个组件

php - Laravel 5 项目结构(插件系统)

javascript - 选择选项上的输入类型文件