title: Extending Blade in Laravel - Creating a custom form object
body: <p>The <a href="http://laravel.com/docs/master/blade#extending-blade" rel="nofollow">documentation on extending blade in Laravel 5</a> doesn't seem to have much depth and i'm struggling to understand if what I want to do is possible.</p>
  
  <p>NOTE: I am using Laravel 5.1</p>
  
  <p>This is the only example the Laravel Docs give for extending blade.</p>
  
  <pre><code>Blade::directive('datetime', function($expression) {
      return "&lt;?php echo with{$expression}-&gt;format('m/d/Y H:i'); ?&gt;";
  });
  </code></pre>
  
  <p>Now what I want to do is have a blade file that looks like this:</p>
  
  <pre><code>@form('horizontal')
      {{ $form-&gt;text('email') }}
      {{ $form-&gt;text('password') }}
      {{ $form-&gt;submit }}
  @endform
  </code></pre>
  
  <p>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</p>
  
  <p>After a bit of Googling and just messing around I have found I can do something like this:</p>
  
  <pre><code>\Blade::directive('form', function($expression) {
      return '&lt;?php $form = new App\Form'.$expression.'; ?&gt;
      &lt;?php echo $form-&gt;open(); ?&gt;';
  });
  </code></pre>
  
  <p>(This was updated from a previous edit)</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <h1>UPDATE HTML MACROS</h1>
  
  <p>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:</p>
  
  <pre><code>@form('horizontal')
      {{ $form-&gt;text("email", $user-&gt;email, 'Email') }}
  @endform
  </code></pre>
  
  <p>The Form class might then look something like this:</p>
  
  <pre><code>class Form
  {
      public $direction;
  
      public function __construct($direction)
      {
          $this-&gt;direction = $direction;
      }
  
      public function text($name, $value, $label)
      {
          return $this-&gt;wrap('&lt;input type="text" value="'.$value.'" /&gt;', $name, $label);
      }
  
      public function wrap($element, $name, $label)
      {
          if($this-&gt;direction == 'horizontal') {
              //Horizontal
              return '&lt;div class="form-group"&gt;
                  &lt;label class="col-sm-2 control-label" for="'.$name.'"&gt;'.$label.'&lt;/label&gt;
                  &lt;div class="col-sm-10"&gt;
                      '.$element.'
                  &lt;/div&gt;
              &lt;/div&gt;';
          } else {
              //Vertical
              return '&lt;div class="form-group"&gt;
                  &lt;label for="'.$name.'"&gt;'.$label.'&lt;/label&gt;
                  '.$element.'
              &lt;/div&gt;';
          }
      }
  }
  </code></pre>
  
  <p>As far as i'm aware HTML Macro's cannot achieve this sort of thing.</p>
  
  <p>This is all pseudo example code, so apologies for any errors. I believe the basic premise of it should be clear though.</p>