Advertisement
  1. Code
  2. PHP
  3. Laravel

Five Hidden Gems of Laravel

Scroll to top

Many developers who use Laravel are probably only barely scratching the surface of what the framework has to offer. While the documentation does cover the most common use cases and the obvious features, it doesn’t cover everything. 

Don’t get me wrong, the documentation is fine, it’s just that there’s so much you can do, it’s hard to document everything. Because of that, we're going to take a look at some of the hidden gems that lurk within Laravel.

Cascading Views

Available since: v4.0.0
Documented: No

Views are able to cascade much the same as configuration files. Cascading views are extremely useful when developing an extendable theming system. Consider the following directory structure.

1
/app
2
    /views
3
        /blog
4
            /index.blade.php
5
/themes
6
    /default
7
        /views
8
            /blog
9
                /index.blade.php
10
            /theme.blade.php

The idea is that when we return View::make('theme::blog.index'); it will first look in the themes/default/views directory and then, if it can’t find the view, fallback to app/views.

To do this we use View::addNamespace to register our own namespace with the two locations.

1
View::addNamespace('theme', [
2
    base_path().'/themes/default/views',
3
    app_path().'/views'
4
]);

Collections

Available since: v4.0.0
Documented: Partially

Collections are a great way to interact with and manage arrays. Collections have a variety of handy methods and implement a number of useful interfaces such as ArrayableInterface, IteratorAggregate, and JsonableInterface.

Let’s say we’re building a small blogging engine that uses flat files for storage. We want to be able to perform operations such as sorting, filtering, and pagination.

Implementing the blogging engine is beyond the scope of this article, but let’s imagine we have an array, $articles, and each member of the array is an instance of an Article class. All we then need to do is get a new instance of Collection and give it our array of articles.

1
$articles = new Illuminate\Support\Collection($arrayOfArticles);

Sorting

Using the collection we can sort our articles. Let’s sort our articles and show the most recently updated articles first. For the sake of this article, let’s imagine that when loading the articles from the file system we set the updatedAt property to the last modified time of the file.

1
$articles->sortByDesc(function ($article) { 
2
    return $article->updatedAt; 
3
});

The sortBy and sortByDesc methods accept a callback, this callback should return a value which can be used for sorting the collection. In our case, we can simply return the articles last modified time and the collection can sort based on that.

Filtering

Similar to sorting, we can also use the collection to filter our articles much like a WHERE clause in MySQL. Let’s filter our articles based on a search that may have been run.

1
<?php
2
3
$searchQuery = 'Laravel rocks!';
4
5
$results = $articles->filter(function ($article) use ($searchQuery) {
6
    return preg_match(sprintf('/%s/m', $searchQuery), $article->body);
7
});

The filter method actually returns a new instance of Illuminate\Support\Collection so we need to assign it to the $results variable. This new collection will contain only the articles that mentioned “Laravel rocks!” in the body.

Pagination

Using the collection we can paginate our articles so we don’t have too many articles appearing on a single page.

1
$perPage = 1;
2
3
$page = Input::get('page', 1);
4
5
if ($page > ($articles->count() / $perPage)) {
6
    $page = 1;
7
}
8
9
$pageOffset = ($page * $perPage) - $perPage;
10
11
$results = $articles->slice($pageOffset, $perPage);

Using the slice method, we extract a portion of the articles in the collection and assign it to the $results variable. 

This example could then be taken even further by creating a new instance of Laravel’s Paginator class. That way it can generate all the page numbers and links for you.

There’s More!

We could get a random article:

1
$article = $articles->random();

We can also iterate over our collection of articles as though it were a regular array. This is all thanks to the IteratorAggregate and ArrayIterator interfaces.

1
foreach ($articles as $article) {
2
    echo $article->body;
3
}

And we can even transform our articles to a regular array or to its JSON representation.

1
$array = $articles->toArray();
2
$json = $articles->toJson();

One of the coolest methods is probably groupBy, which allows us to group articles by a specific key. Imagine each article had some meta data at the top which was parsed and stripped from the articles body.

Although the parsing of this meta data is beyond the scope of this article, we’ll assume that it’s parsed and is a property on the Article instance. You could then use groupBy to group the articles by the category they were posted in.

1
$results = $articles->groupBy('category');

All articles that share the same category will be grouped. You could then get the articles for a specific category.

1
foreach ($results->get('tutorial') as $article) { 
2
    echo $article->body; 
3
}

Collections are one of the best hidden gems Laravel has to offer.

Regular Expression Filters

Available since: v4.1.19
Documented: No

Filtering routes in Laravel is a common task that many of us do in all of our projects. A filter allows you to perform tasks such as user authentication or rate limiting, either before or after a route is fired. We create filters using Route::filter and can apply them to individual routes, a route group, or by using Route::when and applying to a matched pattern.

1
Route::filter('restricted', function($route, $request, $group)
2
{
3
    // Restrict user access based on the value of $group
4
});
5
6
Route::when('admin/*', 'restricted:admin');

In this example, we create a restricted filter which expects a single parameter, $group. The $route and $request parameters are always given to a before filter.

But what if we wanted more flexibility? Let’s say we wanted to apply the filter to all the admin routes except for admin/login. We could use a route group and simply move the route in question outside of the group. Or we could use Route::whenRegex and write our own regular expression.

1
Route::whenRegex('/^admin(\/(?!login)\S+)?$/', 'restricted:admin');

This regular expression simply makes sure that it is only applied to routes that start with admin and are not followed by /login, but can be followed by anything else. Excellent. We now have our restricted:admin filter applied to all routes except our admin/login route.

The Message Bag

Available since: v4.0.0
Documented: Partially

You’ve no doubt been using Illuminate\Support\MessageBag for a while now without even realizing it. The biggest role MessageBag plays is containing all of your validation errors when using Laravel’s built in validator.

An $errors variable is available in each view that will contain either an empty MessageBag instance or the instance you flashed to the session with Redirect::to('/')->withErrors($validator);

There’s a good chance that a lot of you may be doing something like this in your forms when displaying an error message beneath a particular input.

1
{{ Form::text('username', null) }}
2
@if($errors->has('username'))
3
    <div class="error">{{ $errors->first('username') }}></div>;
4
@endif

You can actually remove that if statement entirely and use the second parameter of the first method to wrap the message in the div.


1
    {{ Form::text('username', null) }}
2
    {{ $errors->first('username', '<div class="error">:message</div>') }}

Much, much, much nicer!

Fluent

Available since: v3.0.0
Documented: Partially

The Fluent class has been around for a long time and it’s actually used within the framework itself when creating migrations with the schema builder. Between Laravel 3 and Laravel 4 the class itself has barely changed, the only big differences are a few more interfaces.

To use the Fluent class all you need to do is get an instance and away you go.

1
$user = new Illuminate\Support\Fluent;
2
$user->name('Jason')->country('Australia')->subscriber();

The instance now has 3 attributes defined, name with a value of Jason, country with a value of Australia, and subscriber with a boolean true value.

Prior to Laravel 4.1 you could only really set and get the attributes from instance. Since Laravel 4.1 you can use the toArray and toJson methods to get the array of attributes and its JSON representation respectively. 

As of Laravel 4.2, the class also implements the JsonSerializable interface meaning you can pass the instance directly into json_encode.

There's Even More!

We've looked at several useful gems of the Laravel framework. But, as you've guessed, there's even more within the framework. 

The best way to find out what else Laravel may have on offer is to dig into the source. It's not as scary as you'd think and you'll learn a whole lot about the framework on which you're building.

If you have additional gems that you've found, don't hesitate to share them in the comments!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.