9
Php

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')
    @parent

    

This 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')

{{ $name }}

Contact: {{ $phone or $cell }}

@stop @section('sidebar')

Sidebar

  • ListOne
  • ListTwo
  • ListThree
  • @stop @include('menu') @yield('content') @yield('sidebar')

    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:

    lv_view

    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 '	

    Sheikh Heera

    Contact: 0123456789

    ' (length=100) 'sidebar' => string '

    Sidebar

  • ListOne
  • ListTwo
  • ListThree
  • ' (length=148)

    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": "\t

    Sheikh 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 an Ajax request because, using $view->renderSections() method we can get only part/section of the page without the page Template/Layout, just for the content section we can use return $view->renderSections()['content'] by checking the request type using Request::ajax() to be sure if the current request is an Ajax request or not, that’s it.

    Latest Blog

    0
    Php

    PHP – 8.0 Match Expression

    In PHP 8.0 there is a new feature or I should say a new language construct (keyword) going to be introduced,  which has been implemented depending […]