An Introduction to Laravel, and its MVC Architecture

16 August 2019

Laravel

  • Clean, modern code.

  • Massive community and countless resources.

  • Both elegant and easy to use.

Preface

In this short introduction to Laravel, we will cover the following basic concepts. Afterward, you should have a basic understanding of Laravel, sufficient to begin creating.

  • MVC Architecture
    • Models
    • Views
    • Controllers
  • Routing, Controllers, and Views
  • Blade Templating Engine
  • Laravel Mix

MVC Architecture

MVC is an acronym for Model-View-Controller

MVC is a software development design pattern, that separates responsibility into three logical components.

  • UI logic in views
  • Input logic in controllers
  • Business logic in models (complex code typically interacting with a database)

The process flows as such:

  1. The user navigates to example.com and submits a contact form, sending a POST request to a controller.
  2. The controller receives the request, and sends the form data to a model.
  3. The model stores the form data in the database, and returns to the controller.
  4. The controller then returns a view.
The diagram below, illustrates the flow of a basic MVC application.
MVC

Routing, Controllers, and Views

Routes are contained in routes/web.php

In this file, on a fresh install, you will find the following route:

Route::get('/', function () {
    return view('welcome');
});

This defines the route for the URL /

In this route, we are simply saying, if the user requests the route / we will serve the view welcome.blade.php

The directory containing our view files is resources/views/

So when the user goes to example.com, we will serve resources/views/welcome.blade.php

This is great for simple pages that don’t require much logic, but if we want to do anything more complex, we will want to specify a controller to handle that logic.

For example, if we want to access information from a database, or work with any information from the request, like a form input or a logged in user’s id, we will want to define our own controller.

Create a route

Let’s create a route for an about page, and create a controller to pass some information to the view.

In routes/web.php we will add the following:

Route::get('about', 'AboutController@index');

This creates a route for example.com/about that sends the request to the controller AboutController

Create a Controller

Now we will create the controller.

While logged in through ssh, at the application root, we will issue the command: php artisan make:controller AboutController

This will create the file app/Http/Controllers/AboutController.php

While you can create this file manually, using the artisan command automatically generates the file with some necessary boilerplate code.

Navigate to app/Http/Controllers/AboutController.php and you should see the following:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AboutController extends Controller
{
    //
}

For now, don’t worry about what any of this means. We’re simply going to add the index method that we specified in the route Route::get('about', 'AboutController@index');

Modify the file as such:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AboutController extends Controller
{
    public function index() 
{
    $someVariable = 'some string';

    return view('about', [
        'viewVariable' => $someVariable,
    ]);
}
}

This serves the about view, with the data contained in $someVariable that will be accessible in the view, by the variable $viewVariable

Create a view

In resources/views/ create a new file named: about.blade.php

In this file, add the following:

<html>
    <head>
        <title>App Name</title>
    </head>
    <body>
        <div class="container">
            {{ $viewVariable }}
        </div>
    </body>
</html>

The curly brackets around $viewVariable is blade syntax that is basically saying, filter this data and output it to the page.

You might sometimes run into a scenario where you don’t want that data to be filtered. In these cases you can use {!! $viewVariable !!} The exclamation marks stand for ‘Danger, Will Robinson!’ (not really, but they should)

Now if you view example.com/about you should see ‘some string’ output to the page. Congratulations!

Blade Templating Engine

Blade is a simple and powerful PHP templating engine. Blade allows you to write clean and efficient templates, without giving up any control (you can use PHP in the template if you desire). Despite the power Blade gives you to create templates, it adds nearly no overhead, as the templates are compiled into plain PHP, and cached until they’re modified.

Blade templates live in resources/views/ and exist in the following format: example.blade.php

welcome.blade.php contains the default view on a fresh Laravel installation. Inside of it, you will see some familiar HTML content, along with some Blade directives.

Below, is an example of how you might use an if statement in a Blade template.

@if($someVariable === 'some string')
    {{ $variableToOutput }}
@endif

This simply says, if the data contained in $someVariable is equal to ‘some string’, then output the contents of $variableToOutput

Here’s another example using a pretty cool Blade directive, “forelse.”

In this example we’ll pretend that we want to iterate through an array to create an unordered list.

<ul>
@forelse($array as $key => $value)
    <li>{{ $key }} {{ $value }}</li>
@empty
    <li>I get output if $array is empty.</li>
@endforelse
</ul>

You can even check whether a user is authenticated, right inside the template.

@auth
    The user is authenticated...
@endauth

@guest
    The user is not authenticated...
@endguest

There are many more directives available, but let’s move on to the main feature. Templating.

Blade templates can inherit from other templates using the @extends directive

Let’s create a file, resources/views/layouts/app.blade.php and have the following inside it.

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

This will be our master layout for this example. Our layouts will inherit from this template, so that we only have to worry about the content that is specific for the view.

Our view will contain the following:

@extends('layouts.app')

@section('title', 'Page Title')

@section('content')
    <p>This is my body content.</p>
@endsection

We specify that we want to inherit from the file resources/views/layouts/app.blade.php by using @extends('layouts.app')

We specify that this view’s title should be Page Title

The contents of @section('content') will be filled in the inherited layout, in the location of @yields('content')

Blade has much more to offer as well. If you want to learn more, check out the documentation here: https://laravel.com/docs/5.8/blade

Laravel Mix

The last section we need to cover, is Laravel’s asset pipeline tool, Laravel Mix.

Laravel mix is an API to easily define webpack configurations for asset compilation. It allows you to specify javascript and CSS to be compiled, in an extremely simple way.

Look in the root directory for webpack.mix.js and in it, you will see the following:

const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

This specifies that we have a file resources/js/app.js that should be processed and output to public/js and we have the file resources/sass/app.scss that should be processed and output to public/css

I should also mention that public is our document root, so example.com/textfile.txt would exist at public/textfile.txt

If we wanted to add another javascript file for to use only on a certain page, we need to add that to our mix configuration like this:

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .js('resources/js/another.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

We could also add another sass file in a similar fashion. And we could also opt for less instead of sass like this:

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .less('resources/less/app.less', 'public/css');

To execute the build process for applications in development, in our application root, we need to execute the following command:

npm run dev

Or, if you’re actively working with the javascript or css, you can issue the following to automatically compile when a file is modified:

npm run watch

For applications in production, use the following instead, which will also minify the output:

npm run production

The End

Go Forth and Build

Categories: