In the previous article, we added user registration functionality to our project. In this article, we will focus on defining access and restrictions for users using middleware in Laravel. Properly defining access is crucial for any website, as we want to control what actions users can perform. For example, as you see in previous article, we don’t want just anyone to be able to add a new task to our site. We can achieve this by using middleware, let’s deep dive into middlewares in Laravel.
Middlewares
As the name suggests, Middlewares just like pipelines are commands that sit between our request to the server and the server’s response. You might be familiar with the Auth middleware from prior lesson.
Let’s get back to our project. If you navigate to the app/Http/Middleware
directory, you will find some predefined middlewares. For example, one of these middlewares is PreventRequestsDuringMaintenance
. When you activate this middleware, users will encounter a 503 error or a message indicating that the service is unavailable usually during you perform updates or maintenance on your service.
In Laravel, the php artisan down
command is used to activate this mode, and php artisan up
is used to stop it:
As you see in following pic when your app is in the maintenance mode then the middleware prevents any requests from being executed:
Certainly, it is also possible to exclude specific endpoints from the maintenance mode, To do that you need to add your desired endpoint into the except
array:
class PreventRequestsDuringMaintenance extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array<int, string>
*/
protected $except = [
//
];
}
If you recall from the previous tutorial, you learned that we can add a middleware to an endpoint using the middleware
function. Similarly, you can add a middleware to a group of routes using the group
function, as shown below.:
// one route
Route::post('logout', LogoutController::class)->middleware('auth');
// or a group of routes
Route::group(['middleware' => 'auth'], function () {
Route::resource('tasks', TaskController::class);
Route::post('logout', LogoutController::class)->name('logout');
});
Create a new Middleware
To create a custom middleware, we will use the following artisan command:
php artisan make:middleware <NameOfMiddleware>
In Laravel, every middleware has a handler
function where you can define its logic. This function takes two inputs: the request object and a closure. The request object allows you to access the data within the request, while the closure is a function that you can invoke to proceed with the middleware pipelines:
public function handle(Request $request, Closure $next)
{
return $next($request);
}
To use this middleware, we need to define it in the kernel.php
file located in the Http folder. Let’s take a closer look at the kernel.php
file. It contains three arrays, each serving a specific purpose.
The first array, middleware
, is meant for middlewares that are globally applied to all requests.
The next array, middlewareGroups
, is used for applying middlewares to specific group of routes.
Finally, we have the routeMiddleware
array. In this array, middlewares are defined with a key, allowing us to apply a middleware to a specific route. For instance, if you look at the list, you will see auth
mentioned, which demonstrates how we can apply it to desired routes.
Now, let’s try something interesting.
Multilingual Laravel Website
Sometimes we may need to make our website multilingual, and Laravel provides a convenient tool to facilitate this.
To set up language resources in Laravel, we first need to run the following command:
php artisan lang:publish
After running this command, you will notice that in the main directory of your project, there are PHP translation resources that include arrays with keys. These keys represent default terms that can be found in any application. You can add translations to these keys. However, having only an English resource might not be sufficient. Let’s say we want to add French as another language. It can be time-consuming to manually translate all the files and key values into French, especially if you’re not proficient in French.
Luckily, there is another way! You can add laravel-lang package to your project that simplifies the process. By running the following command, you can install the package and add French language resources to your lang directory:
composer require laravel-lang/common --dev
php artisan lang:add fr
php artisan lang:update
Once you have set up the language resources, you can proceed to add translations for specific keys. For example, let’s say we want to add a translation for the key “welcome” in both English and French languages. You can do it like this:
>> lang/en.json:
"welcome": "Welcome to Laravel101 tutorials",
>> lang/fr.json
"welcome": "Bienvenue dans les tutoriels Laravel101",
You might be wondering how to use it, right? Well, it’s quite simple!
To utilize it, you just need to use a handy helper function called __('key')
within your Blade files. For example, if you have a "welcome" key in your language resources, you can display it on the home page of your app like this:
@extends('layouts.app')
@section('title', 'Home Page')
@section('content')
<div class="flex flex-center justify-between mb-4">
<h1 class="text-xl font-bold ">{{ __('welcome') }}</h1>
</div>
@endsection
Additionally, to change the locale of your application to use a specific language, you can modify the locale
value inside the config/app.php
file of your project. Now set the locale
to 'fr' and here is the result:
When it comes to translation, there are a few tips that can come in handy. One useful technique is to use the getLocale
function to set the language in an HTML tag, like this:
<html lang="{{ app()->getLocale() }}">
Another useful feature is the ability to include dynamic values within translations:
By passing an array of key-value pairs as a second parameter to the helper function, you can specify the keys you want to use for dynamic values. For example:
__('hello', ['user' => $username])
In the above example, the key 'user' is defined for this purpose, allowing you to insert the $username
dynamically into the translation.
There is also a function called trans_choice
that lets you translate selectively based on a given input. It allows you to choose between singular and plural forms of a word. For instance, consider the following example:
// translate file
return [
'model' => 'book|books'
];
// in blade:
{{ trans_choice('default.model', 1 ) }}
>>> book
{{ trans_choice('default.model', 2 ) }}
>>> books
Great! We’ve covered the basics of translation files and the tools Laravel provides for language management. Now, let’s explore how we can dynamically set the language based on user selection using functions and sessions in Laravel.
Assuming the default language of our site is English, we can configure the language and define the necessary translation keys using helper functions in the config
files.
To handle language selection by the user, we can create a controller called LocaleController
and define a store
function as follows:
use Illuminate\Http\Request;
class LocaleController extends Controller
{
public function __invoke(Request $request)
{
session(['locale' => $request->locale]);
return redirect()->back();
}
}
To access this function, we define an appropriate route:
Route::post('/locale', LocaleController::class)->name('locale.store');
To display a language selection menu in the navigation blade file, you can add the following code:
The menu mentioned above allows users to send a request to the server to indicate their desired language. However, there’s still more work to be done. We need to retrieve the selected language from every request on the server, and this can be achieved using a middleware:
php artisan make:middleware SwitchLocaleMiddleware
Once you’ve executed the command, navigate to the app/Http/Middleware
directory and define the middleware as follows:
public function handle(Request $request, Closure $next): Response
{
if (Session::has('locale'))
App::setLocale(Session::get('locale'));
return $next($request);
}
Here we use two object: Session
, and App
which defined globally and are accessible with session()
and app()
you can access session from request like $request->session()
The App facade is a powerful object that enables us to work with various services within our project. Today, we’ll use it to set the app’s locale.
The Session provides a convenient and straightforward way to access data specific to the current user’s request. In Laravel, you have multiple options for managing session data, including file, Redis, encrypted cookies, and database. By default, Laravel is configured to use the file session driver, which is suitable for many applications. In our case, we’re using the session to store the user’s locale.
Now, open the Kernel
file located in the app/Http
directory and add this middleware to the end of the $middlewareGroups
array and in web group because the session driver defined here, like this:
protected $middlewareGroups = [
'web' => [
// Other middleware entries...
\App\Http\Middleware\LanguageMiddleware::class,
]
];
That’s it! By following these steps, you’ll have a multilingual site where you can define the translation keys in the respective language folders. The final output will be as follows :
That’s fantastic 😍!
In this tutorial, we explored Laravel Middlewares and discovered how they can be used to enhance our application, particularly in achieving multilingual functionality.
I hope you found this tutorial helpful, happy coding!
Top comments (2)
Very good series and clear explanation. Tnx
It's great to hear that, Thank you