I'm using the Post/Redirect/Get (PRG) pattern in my Laravel controllers to prevent duplicate form submission.
It works well when I don't use layouts or when my layouts don't use any variable. The problem is my layout uses a variable named $title
. When I load the view and the layout without redirect it works well, the title set in the controller is passed to the layout, but after processing a form and redirecting to the same route which uses the same layout and the same controller method I get a "Undefined variable: title" error coming from my layout file.
Here is my code:
File: app/routes.php
Route::get('contact', array('as' => 'show.contact.form', 'uses' => 'HomeController@showContactForm'));
Route::post('contact', array('as' => 'send.contact.email', 'uses' => 'HomeController@sendContactEmail'));
File: app/controllers/HomeController.php
class HomeController extends BaseController {
protected $layout = 'layouts.master';
public function showContactForm()
{
$this->layout->title = 'Contact form';
$this->layout->content = View::make('contact-form');
}
public function sendContactEmail()
{
$rules = ['email' => 'required|email', 'message' => 'required'];
$input = Input::only(array_keys($rules));
$validator = Validator::make($input, $rules);
if($validator->fails())
return Redirect::back()->withInput($input)->withErrors($validator);
// Code to send email omitted as is not relevant
Redirect::back()->withSuccess('Message sent!');
}
}
File: app/views/layouts/master.blade.php
<!DOCTYPE html>
<html>
<head>
<title>{{{ $title }}}</title>
</head>
<body>
@yield('body')
</body>
</html>
File: app/views/contact-form.blade.php
@section('body')
@if (Session::has('success'))
<div class="success">{{ Session::get('success') }}</div>
@endif
{{
Form::open(['route' => 'send.contact.email']),
Form::email('email', null, ['placeholder' => 'E-mail']),
Form::textarea('message', null, ['placeholder' => 'Message']),
Form::submit(_('Send')),
Form::close()
}}
@stop
I don't understand why after redirecting the next line of code is ignored
$this->layout->title = 'Contact form';
I've tried with Redirect::action('HomeController@sendContactEmail');
or Redirect::route('show.contact.form');
but the result is the same.
The controller in charge of rendering that view is exactly the same before the redirect than after the redirect, and it has no business logic at all, so why it only works on the first case but not in the second?