The documentation on extending blade in Laravel 5 doesn't seem to have much depth and i'm struggling to understand if what I want to do is possible.
NOTE: I am using Laravel 5.1
This is the only example the Laravel Docs give for extending blade.
Blade::directive('datetime', function($expression) {
return "<?php echo with{$expression}->format('m/d/Y H:i'); ?>";
});
Now what I want to do is have a blade file that looks like this:
@form('horizontal')
{{ $form->text('email') }}
{{ $form->text('password') }}
{{ $form->submit }}
@endform
Then I want a new $form object to be created whenever I use @form and have it available to use after I use @form but it doesn't need to be available after @endform
After a bit of Googling and just messing around I have found I can do something like this:
\Blade::directive('form', function($expression) {
return '<?php $form = new App\Form'.$expression.'; ?>
<?php echo $form->open(); ?>';
});
(This was updated from a previous edit)
That's most of the way there. I have a $form object and can create a new form and I can send a custom param to that form object. I can also use the $form object after @form. Of course it will be available throughout the view, that's not perfect, but not necessarily a problem.
However since I seem to be doing something that is completely undocumented I fear I may be doing something wrong, or that I may run into problems later.
I should also note that every single guide I have found online refer to $compiler->createMatcher and $compiler->createPlainMatcher but both of these seem to be removed in Laravel 5.1.
Can anyone offer any insight into how blade extensions work and suggest better ways of doing this? Right now it seems to work just about, but feels very 'hacky' and perhaps not safe to rely on going forward.
UPDATE HTML MACROS
To update on a use case for this based on an answer below suggesting HTML macros. CSS Framework Bootstrap includes different formatting for vertical and horizontal forms. The purpose of this functionality would be to make it easy to switch between these two, an example is below:
@form('horizontal')
{{ $form->text("email", $user->email, 'Email') }}
@endform
The Form class might then look something like this:
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>';
}
}
}
As far as i'm aware HTML Macro's cannot achieve this sort of thing.
This is all pseudo example code, so apologies for any errors. I believe the basic premise of it should be clear though.
You might want to look into this plugin "illuminate/html": "~5.0".
You can do things like open forms which these two method will do.
As a bonus you also get many other items.
And many others, see the source.
As far as your original question, you can always use the 5.0 function and just put the original method
createOpenMatcher
in your service provider. See my answer here.Update per comment
So per you comment, the Illuminate form helper will do what you are asking.
Which renders as
Anything passed to the array is added to the form tag.
I might not understand your question 100%, but I think you may be trying to solve with Blade extensions something that might be much easier to solve with your code editor or the Form helper plugin. Maybe you could add the two types of HTML you are trying to generate and we could discuss that?
I use both PhPStorm and Sublime text. Both of these have options where you can include code snippets of text. In PhPStorm they are called Live Templates and Sublime calls them snippets.
I use a
textfield
tab live template for PhPStorm for my text fields.Which gives you the render html
Although I do extend Blade from time to time. I have found that for the majority of times, when I want to extend it, there is usually an easier way.
Final Edit
Why don't you use CSS?