Laravel – My Journey – Part 4 – Room With a View


No-one is more surprised than me that this series has reached its fourth instalment. So far, I’ve laid the groundwork for my Laravel Shopping List’s backend. I have a database, I have the models, I have the controllers. But I haven’t anything to show the user yet. I’ll need that. Let’s see how Laravel’s Blade templating system takes my data and presents it to the user …

Previous articles in this series:
Important Note/Disclaimer
This is not a tutorial, nor an example of best practice. The techniques described in this article are not to be taken as efficient or secure. At the time of writing, I am a relative newcomer to Laravel, object-oriented programming, and the MVC paradigm. I won't be explaining every detail. I don't know all the theory. I'll probably get stuff to work and not know how I did it. I'll probably write things that are clearly untrue or, at best, inaccurate. This is me just finding my way ...

In Part Three, we saw how my Laravel application’s ProductController controller takes care of the CRUD operations for my products. Not only can a controller retrieve and manipulate data from the database, it can also pass that data to a view so that it can be presented to the user in response to a request via the user’s browser.

MVC architecture

Laravel uses the Blade templating system as the basis for presenting HTML web pages to the user. Data that is passed to the view via a controller is parsed by Blade before being returned to the user. Let’s see how that works using my application’s products as an example.

Products Index Page

This is my product’s index page at the /product URL. As you may remember from the previous article, the function of the index page is to “display a listing of all instances of the resource“. My translation of this is: “Show me a list of all of my products“. 

The index() method of my product controller is responsible for retrieving product data and passing that data to a view. As a reminder, here is the code for that method (simplified):

 * Display a listing of the resource.
 * @return \Illuminate\Http\Response
 public function index()
     // Get logged in user
     $user = auth()->user();
     // Get user's products, paginate
     $products = $user->products()->orderBy('title');
     // Load view and pass through products collection
     return view('products.index', compact('products'));

The line of code in bold returns the products.index view, passing along the contents of $products so that is available to that view. $products contains all of the products that belong to the currently logged-in user, ordered alphabetically by the title of the product.

The products.index view refers to a Blade file that is located in my application’s resources/views/products/ folder. It is called index.blade.php.

Blade file within folder structure

As you can see, there are other Blade files, named create.blade.php, edit.blade.php, and show.blade.php. These view files are responsible for handling the data passed to them by the product controller method with the same name as the view file. For example, the create() controller method returns the create.blade.php  file for displaying the form to create a new product:

 * Show the form for creating a new resource.
 * @return \Illuminate\Http\Response
 public function create()
     // Load view
     return view('products.create');

But that accounts for only four of the seven controller methods. What about store(), update() and destroy()?

Well, those methods don’t require a view to be returned.  For example, the store() method takes the data that the user types into the ‘Add Product’ form (which is generated by the create() controller method and create.blade.php view)  and adds that data into the database. After that happens, the application redirects to the products index page (/products). No store.blade.php view is required.

In the finished application, flash messaging is used to inform the user that their product has been added. Here’s an excerpt from the product controller store() method that shows this:

// Populate product table
// Message
    'message', 'Your product has been added.'
// Redirect to view
return redirect()->route('product.index');

I’ve briefly described how my data gets passed to the view. Now I will demonstrate how the index.blade.php Blade file takes that data and displays it to the user.

Blade – Displaying a List of Products

In simple terms, my product index page needs to display a list of products. Those product details are contained in $products. This has been passed from the controller to the view. But what exactly is contained in $products?

Here is the result of a dump and die on $products:

Die and dump of $products

So we have a Collection which contains five items (one for each of my products). Expanding the items and their attributes reveals the data we are interested in, namely the product’s title and other information.

We can use Blade directives to display our data in a form suitable for output to the  browser. For example, the forelse directive provides a convenient way to loop through a collection (much like a standard PHP foreach loop) and also provides an option if there are no results to display:

    @forelse ($products as $product)
        <li>{{ $product->title }}</li>
        <li>No products</li>

The above code loops through each item in the $products collection, displaying a list item for each product. This generates the following HTML:

    <li>Toilet Roll</li>
    <li>Washing Up Liquid</li>

Clearly this is a very simplified example, but forelse loops can be used to output formatted tables of results or in any other format supported by HTML/CSS:

There’s a lot more to Blade templates than has been described here. If you would like to find out more, visit the Laravel Blade documentation.

I’ve now completed my brief overview of Laravel’s MVC architecture by applying it to the creation of my Shopping List application.

Further articles in this series will look at:

Feel free to leave comments below. I realise this has been quite a simplistic overview of Laravel, so if you would like further information on any aspect that I have touched upon, please let me know.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.