Laravel: easy asset management without any extra packages

There are many packages available for asset management in Laravel. Although some are pretty good, I think asset management packages aren’t really necessary in Laravel thanks to the Blade template engine. So with those words, let’s put my money where my mouth is and show you the way I’m managing my assets in Laravel.

The idea behind this solution is a master page with sections. The example below is for Laravel 5 with the HTML package, but can be used in any Blade template driven application. This idea matches my opinion that assets are mostly view specific and therefor should be determined in the view and not in the controller. So let me show you how I handle my assets.

Create master page

Start by creating a master page at app/layout/master.blade.php or any other location that matches your project organisation. The master page contains the head and body tag, CSS, JS (which are used for the whole application) and some blade sections:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ $title }}</title>

    {!! Html::style('/assets/css/style.min.css') !!}

    @yield('header.styles')

    @yield('header.scripts')
</head>
<body>
    @yield('content')

    @yield('footer.scripts')
</body>
</html>

This is just a regular HTML page in a Blade template. The four sections take care of the rest:

  1. header.styles: extra CSS files which should be loaded while the page is loading
  2. header.scripts: extra JS files which should be loaded while the page is loading
  3. content: the page itself
  4. footer.scripts: extra JS files which can be loaded after the page is loaded

You can add an extra section for styles which can be loaded after the page is loaded. I haven’t done that because of the effects this can have on smartphones.

Build the page

With this knowledge, we can build the page itself and add the assets. For this example, let’s build a login page. The first thing we need to do is extending the master template:

@extends('app.layout.master')

The second thing is creating the content section, which holds the page itself. In this case the form for the login page:

@section('content')
{!! Form::open() !!}
    <div class="form-group">
        {!! Form::label('email', 'Emailadres', ['class' => 'control-label']) !!}
        {!! Form::text('email', old('email'), ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::label('password', 'Wachtwoord', ['class' => 'control-label']) !!}
        {!! Form::password('password', ['class' => 'form-control']) !!}
    </div>
    <div class="form-group">
        {!! Form::submit('Inloggen', ['class' => 'btn btn-primary']) !!}
    </div>
{!! Form::close() !!}
@endsection

For this example: let’s say you have some fancy ajax login and therefor you have created a CSS and Javascript file and want to add it on this page only:

@section('header.styles')
    {!! Html::style('/assets/css/my-fancy-login.min.css') !!}
@endsection

$section('footer.scripts')
    {!! Html::script('/assets/js/my-fancy-login.min.js') !!}
@endsection

Result

When the Blade compiler compiles this page, it places the CSS in the header and script before the </body> tag:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{ $title }}</title>

    <link media="all" type="text/css" rel="stylesheet" href=".../assets/css/style.min.css">

    <link media="all" type="text/css" rel="stylesheet" href=".../assets/css/my-fancy-login.min.css">
</head>
<body>
    .. login form ..

    <script src=".../assets/js/my-fancy-login.min.js"></script>
</body>
</html>

Leave a Reply

Your email address will not be published. Required fields are marked *