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,我们可以讨论一下?
我同时使用 PhPStorm和 Sublime text 。这两个选项都有可以包含文本代码片段的选项。在 PhPStorm 中它们被称为 Live Templates Sublime 称它们为 snippets .
我使用 PhPStorm 的 textfield
tab 实时模板作为我的文本字段。
<!-- $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/