Laravel – Useful RenderSections Method In View
In Laravel PHP MVC Framework
, to send content back to the browser one must use a return
keyword from a controller with the rendered content, like:
return View::make('home.index');
This is a very simple example and very common in any Laravel
application and any developer knows what is this code for, obviously any developer means a developer who knows about Laravel PHP MVC Framework
and have a very basic idea on this. Anyways, I’m going to discuss about the View
class of the framework and it’s hidden (not exposed on documentation) powerful methods and various ways that developers can utilize to render a view.
Before you go further make sure you are familiar with Laravel Blade Templating System
and if not then you should get the idea about it at first and you can find a very good information on their website in the Laravel Blade Templating section.
In Laravel
, the presentation of the page divided in two parts, Layout
and View
, actually, both are views but the Layout
is mainly the the template of the page which defines the main structure of the page and views
are small individual parts of a page and each view basically is a file with required content for a page. So, whenever a view is returned from a controller action, the default master template/layout nests that view, the rendered page content into itself and become visible on the screen. So, a basic Blade Layout
may look like this:
@section('sidebar') This is the master sidebar. @show@yield('content')
A view (Using Blade) may looks like this:
{{-- Blade Comment: Stored in app/views/home/index.blade.php --}} @extends('layouts.master') @section('sidebar') @parentThis is appended to the master sidebar.
@stop @section('content')This is my body content.
@stop
If one returns return View::make('home.index')
from a controller
then the Master Layout
will paste/mix the content between @section('sidebar')
and @stop
of index.blade.php
file inside it’s own @section('sidebar')
and also the content between @section('content')
and @stop
of index.blade.php
file will be pasted into the place of @yield('content')
of the main layout. So, final result will be (after rendering) this:
This is the master sidebar.This is appended to the master sidebar.
This is my body content.
Ok, enough about View
and Layout
. Now, lets get into the point. How to pass data from controller in to a view ? It’s very simple:
return View::make('home.index')->with('name', 'Sheikh Heera')
So, in the view
the $name
variable will be available to use and it’ll contain Sheikh Heera
and following code (in view) will show the name:
{{ $name }}
Well, nothing new for a Laravel Guy
but the funny thing is that, there are also other ways to set variables in the view and it’s also possible to get a variable from the view or check if a variable exists in the view and someone may render only a part of a view to show in the response, even more fun is that, it’s also possible to slice a part from the view without the whole layout and send the part as json encoded
data to the browser. Often, developers use, a separate template for an Ajax
request to exclude the template body from the response to send only he content part of the response generated by a view file but it’s also possible to use same template for an ajax and a non-ajax request.
Lets dig in to deep:
These are some useful public methods available in the Illuminate\View
object along with others:
// Make/Render the view (In the controller) $view = View::make('home.example') ->with('name', 'Sheikh Heera') ->with('cell', 'none'); // Checks existence of phone variable if(!$view->offsetExists('phone')) { // Set phone variable if doesn't exist $view->offsetSet('phone', '0123456789'); } // Get cell variable and check it's content if($view->offsetGet('cell') == 'none') { // Delete from the view $view->offsetUnset('cell'); } // The example View{{ $name }}
Contact: {{ $phone or $cell }}
Until returning the view
from the controller
the view data won’t be rendered and sent to the browser as a response.
The most interesting part renderSections()
method:
This method can return all the sections of a layout
in an array, for example, I’ve this view
and Layout
:
@extends('layouts.master') @section('content')@stop @section('sidebar'){{ $name }}
Contact: {{ $phone or $cell }}
@stop @include('menu') @yield('content') @yield('sidebar')Sidebar
ListOne ListTwo ListThree
Now, if I write following code:
$view = View::make('home.index') ->with('name', 'Sheikh Heera') ->with('cell', '0123456789'); return $view;
I may get something like this:
But, if I write this code:
$view = View::make('home.index') ->with('name', 'Sheikh Heera') ->with('cell', '0123456789'); return $view->renderSections()['content'];
Only following HTML
code will be sent to the browser:
Sheikh Heera
Contact: 0123456789
Because $view->renderSections()
returns an array like this:
array (size=2) 'content' => string '' (length=100) 'sidebar' => string 'Sheikh Heera
Contact: 0123456789
' (length=148)Sidebar
ListOne ListTwo ListThree
So, it’s clear that, return $view->renderSections()['sidebar'];
will return the HTML
code of sidebar only and it’s without the the layout
so, it’s possible to use same layout
and view
for an Ajax
request as well. For example, if I make an Ajax
request like this:
$.get('page', function(data){ $('#pageContent').html(data); });
Then I can use code like this:
if(Request::ajax()) { $view = View::make('home.index') $view = $view->renderSections(); return join($view, ''); }
The use of join($view, '')
is required because renderSections()
method returns all the sections in an array but it’s not possible to sent an array as response, it has to be string
so, join($view, '')
just combines the whole array (with multiple sections) into String
and it’s just like explode('', $view)
function. After join('', $view)
the actual content looks like this:
string 'Sheikh Heera
Contact: 0123456789
'Sidebar
ListOne ListTwo ListThree
This is plain HTML
so on the client side (using jQuery) $('#pageContent').html(data)
can set the returned data as HTML
an element.
It’s also possible to convert the data to json string
using json_encode($view)
, for example, check this:
if(Request::ajax()) { $view = View::make('home.index') $view = $view->renderSections(); return json_encode($view); }
This will produce something like this (in String
form):
{ "content": "\tSheikh Heera<\/h2>
Contact: 0123456789<\/p><\/div>", "sidebar": "\t
Sidebar<\/h1>
ListOne<\/li> ListTwo<\/li> ListThree<\/li><\/ul><\/div>" } So, on the client side (for Ajax request), it’s possible to use the
json response
like this:$.get('test', function(data){ data = $.parseJSON(data); $('#pageContent').html(data.content); $('#sidebar').html(data.sidebar); });So, it’s possible to use the same
Layout
settings even for anAjax
request because, using$view->renderSections()
method we can get only part/section of the page without thepage Template/Layout
, just for thecontent
section we can usereturn $view->renderSections()['content']
by checking the request type usingRequest::ajax()
to be sure if the current request is anAjax
request or not, that’s it.