Multi-language Roles and Permissions in Spatie Package (laravel-permission)

This is an easy way to use multi-language for Roles and Permissions ‘Spatie Package (laravel-permission)’.

Tutorial for Laravel ≥ 5.6

In our tutorial we need 3 Packages:

1- Install laravel-permission

composer require spatie/laravel-permission

2- Install laravel-translatable

composer require spatie/laravel-translatable

3- Install slugify

composer require cocur/slugify

Important: The slugify package is optional.It’s just used if you need easy way to generate slug

After we finish install and configure all packages. You need to know how to use it together.

Step 1: Make some changes inside the laravel-permission package.

  • Add new migration
php artisan make:migration add_slug_to_permission_table --table=permissions

After add the new migration we will need to Copy/Paste this code below.

Let’s we explain what we will do:

  • Add new field to the permission and role tables
  • The name of field slug (You are free to choose other name)
class AddSlugToPermissionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$tableNames = config('permission.table_names');

Schema::table($tableNames['permissions'], function (Blueprint $table) {
$table->string('slug')->after('name')->unique();
});

Schema::table($tableNames['roles'], function (Blueprint $table) {
$table->string('slug')->after('name')->unique();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$tableNames = config('permission.table_names');
if (Schema::hasColumn('permissions', 'slug')){
Schema::table($tableNames['permissions'], function (Blueprint $table) {
$table->dropColumn('slug');
});
}
if (Schema::hasColumn('roles', 'slug')){
Schema::table($tableNames['roles'], function (Blueprint $table) {
$table->dropColumn('slug');
});
}

}
}

Step 2: Override The Permission & Role Models

2.1 Extend the Permission Class from the parent class
2.2 Use laravel-translatable package:

  • Use the HasTranslations Trait (From laravel-translatable package) and add the Field you want to be to be translatable (Examplename’)
<?php

namespace App\Models;

use Spatie\Permission\Models\Permission as SpatiePermission;
use Spatie\Translatable\HasTranslations;

class Permission extends SpatiePermission
{
use HasTranslations;
public $translatable = ['name'];
}

Use the same steps we do for the Permission model for Role Model

<?php

namespace App\Models;

use Spatie\Permission\Models\Role as SpatieRole;
use Spatie\Translatable\HasTranslations;

class Role extends SpatieRole
{
use HasTranslations;
public $translatable = ['name'];
}

By default spatie/laravel-permission use the name to check permissions in the configuration config/permission.php:

‘model_key’ => ‘name’,

Open config/permission.php and change it from ‘name’ to ‘slug

* Ideally, this should match your preferred way of checking permissions, eg:
* `$user->can('view-posts')` would be 'name'.
*/

'model_key' => 'slug',

Example how to check permission of user: $user->can(‘slug’)

Why we change it to slug?
Because the field name will be set in the database like array key=>value and we need to check permission by one simple way , this is why we choose to add the slug field.

Step 3: Add method to store translated permission or role

Permission

use App\Models\Permission;Permission::create([
'name' => [
'fr' => ucfirst(strtolower($request->frensh)),
'en' => ucfirst(strtolower($request->english))
],
'guard_name' => $request->guard,
'slug' => $slug
]);

Role

use App\Models\Role;Role::create([
'name' => [
'fr' => ucfirst(strtolower($request->frensh)),
'en' => ucfirst(strtolower($request->english))
],
'guard_name' => $request->guard,
'slug' => $slug
]);

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store