Tutorial Cara Generate Unique Slug di Laravel 8

Tutorial Cara Generate Unique Slug di Laravel 8

Admin
Admin・ 11 September 2021
10 min read ・ 8881 views

Laravel Unique Slug - Di artikel ini saya akan membagikan tutorial bagaimana cara generate slug di laravel 8 menggunakan helper Str::slug dan tutorial bagaimana cara generate unique slug menggunakan eloquent sluggable package.

Apa itu Slug ?

Slug merupakan bagian dari URL yang mengidentifikasi halaman web tertentu (unique). Contoh slug seperti URL  https://codelapan.com/post-slug, dan berarti slug dari URL tersebut adalah "post-slug". Untuk SEO, sertakan keyword di URL dan buatlah URL yang ramah pengguna.

Generate Slug di Laravel 8

Untuk membuat slug di laravel, sebenarnya kita bisa menggunakan helper yang telah disediakan oleh laravel yaitu Str::slug. Contoh penerapannya seperti di bawah ini.

 public function store(Request $request)
    {
        $post            = new Post();
        $post->title  = $request->title;
        $post->slug = \Str::slug($request->title);
        $post->save();
    }

Dengan kode di atas, maka $post->slug akan mengambil nilai dari $request->title dan mengkonversinya menjadi URL yang user friendly. Jika value dari $request->title sama dengan "Cara Generate Unique Slug di Laravel 8" maka nilai $post->slug akan sama dengan "cara-generate-unique-slug-di-laravel-8". Tapi jika slug bertype unique, maka ketika kita tambahkan data lagi dengan title "Cara Generate Unique Slug di Laravel 8", output yang dihasilkan akan error: "Integrity constraint violation: 1062 Duplicate entry 'cara-generate-unique-slug-di-laravel-8' for key 'posts_slug_unique'".

Bagaimana cara agar ketika kita tambahkan judul yang sama, otomatis akan generate unique slug ?

Oke, di artikel ini, saya akan share bagaimana cara membuat atau generate unique slug di laravel 8. Kita bisa dengan mudah membuat seperti itu dengan eloquent sluggable package. Untuk cara penerapannya di laravel 8 akan dijelaskan step by stepnya di bawah ini.


Generate Unique Slug di Laravel 8

Di tutorial cara generate unique slug di laravel 8 ini, saya akan coba share step by stepnya mulai dari install laravel versi terbaru, membuat post model dan migration file, install package, setup database, setup view dan define rounte.

Install Laravel

//via Laravel Installer
composer global require laravel/installer
laravel new laravel-unique-slug

//via Composer
composer create-project laravel/laravel laravel-unique-slug

Pada langkah yang pertama ini, kita perlu menginstall laravel versi terbaru (saat ini versi 8) yang akan kita coba untuk implementasi generate unique slug di laravel 8. Untuk installasi laravel bisa menggunakan laravel installer atau menggunakan composer seperti contoh di atas.

Silahkan memilih salah satu cara yang ingin digunakan untuk installasi laravel. Dari kedua contoh perintah installasi laravel di atas, akan sama-sama menghasilkan atau generate laravel project dengan nama laravel-unique-slug.

Tunggu hingga proses installasi selesai dan jika sudah selesai, jangan lupa untuk masuk ke direktori project menggunakan perintah cd laravel-uniqe-slug.

Create Post Model & Migration

php artisan make:model Post -m

Langkah kedua, kita akan membuat Post Model & Migration file. Jalankan perintah seperti di atas di terminal. Dari perintah tersebut akan menghasilkan dua file yaitu;

app/Model/Post.php

database/migrations/[timestamp] _create_posts_table.php

Kemudian buka file [timestamp] _create_posts_table.php yang baru saja kita buat dan edit kode di file tersebut menjadi seperti di bawah ini.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug')->unique();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
} 

Setup Database

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_unique_slug
DB_USERNAME=root
DB_PASSWORD=

Setelah selesai membuat Post Modal & Migration file, sekarang kita perlu membuat database baru. Silahkan buat database baru dan jangan lupa menyesuaikan DB_DATABASE di file .env bernilai sama dengan nama database yang telah dibuat.

Kemudian untuk menjalankan semua migration file, jalankan perintah php artisan migrate.

Install Eloquent Slugable Package

composer require cviebrock/eloquent-sluggable

Update Post Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;

class Post extends Model
{
    use HasFactory;
    use Sluggable;

    protected $guarded = [];
    
    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}

Edit file mode Post.php dengan menambahkan trait sluggable dan perlu mendifinisikan abstact method sluggable() seperti contoh kode di atas.

Setup View

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">

    <title>Generate Unique Slug in Laravel 8</title>
  </head>
  <body>
    <div class="container mt-5">
        <div class="row">
            <h1 class="text-center my-3">
                Generate Unique Slug in Laravel 8
            </h1>
            <form action="/" method="POST">
                @csrf
            <div class="mb-3">
                <label for="title" class="form-label">Title</label>
                <input type="text" name="title" class="form-control" id="title">
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
    </div>

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>

  </body>
</html>

Edit file welcome.blade.php yang ada di direktori resources/views menjadi seperti kode di atas. Kode di atas merupakan starter template dari bootstrap 5 dengan penambahan form dengan input field untuk title dan action post.

Setup Route

Route::post('/', function () {
    App\Models\Post::create(['title' => request('title')]);
    return redirect()->back();  
});

Di file routes/web.php, kita hanya perlu mendefinisikan atau membuat route baru seperti di atas. Dengan begitu, ketika kita inputkan title dan klik submit maka data title akan ditambahkan ke table posts di database dan otomatis juga akan generate unique slug.

Eloquest Sluggable Testing

Oke, setelah melewati step by step bagaimana cara generate unique slug di laravel 8 yang diawali mulai dari install laravel, membuat post model & migration, setup database, install sluggable package, setup view sampai setup route, dan sekarang waktunya menguji apakah simple project kita ini sudah berhasil generate unique slug atau belum.

Silahkan jalankan server laravel project dengan perintah php artisan serve, lalu buka laravel project di browser. Cobalah dengan beberapa kali menginputkan data title yang sama.

output: laravel unique slug

Dan jika kita cek di database, maka hasilnya ketika kita input title yang sama beberapa kali, eloquent-sluggable package akan otomatis menambahkan increment counter di akhir slug seperti gambar di atas.

Show Realtime Laravel Unique Slug

show realtime laravel unique slug

Bagaimana cara untuk menampilkan unique slug yang telah digenerate menggunakan eloquent sluggable package secara realtime ? Kita bisa membuat atau menampilkan unique slug yang telah digenerate seperti gambar di atas menggunakan tambahan jQuery. Untuk cara membuatnya akan dijelaskan di bawah ini.

Edit Blade

<div class="mb-3">
    <label for="slug" class="form-label">Slug</label>
    <input type="text" name="slug" class="form-control" id="slug">
</div>

Langkah pertama, buka file welcome.blade.php dan tambahkan kode input field baru seperti kode di atas untuk menampilkan slug yang telah digenerate dan letakkan kode di atas tepat di bawah input field title.

{{-- jQuery Script --}}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
{{-- Check Slug --}}
<script>
    $('#title').change(function(e) {
       $.get('{{ url('check_slug') }}', 
       { 'title': $(this).val() }, 
       function( data ) {
           $('#slug').val(data.slug);
       }
       );
    });
</script>

Kemudian tambahkan jquery dan script untuk memeriksa slug dan menampilkannya di input fileds (di view). Di script tersebut, kita arahkan url ke check_slug dan menampilkan data slug yang telah digenerate ke input field dengan id slug.

Update Route

use Cviebrock\EloquentSluggable\Services\SlugService;
....
....
....
....
Route::get('check_slug', function () {
    $slug = SlugService::createSlug(App\Models\Post::class, 'slug', request('title'));
    return response()->json(['slug' => $slug]);
});

Selanjutnya, buka file routes/web.php dan tambahkan kode route seperti di atas dan jangan lupa untuk menggunakan trait use Cviebrock\EloquentSluggable\Services\SlugService;.

Dengan begitu, sekarang jika kita buka laravel project kita ini di browser maka sudah terdapat tambahan input field baru untuk slug dan jika kita inputkan data title baru di input field title maka secara otomatis di input field slug akan menampilkan slug yang telah digenerate secara realtime menggunakan eloquent sluggable package.

Selamat mencoba. Semoga artikel ini bisa membantu dan sampai jumpa di artikel berikutnya. 😊 🚀 🚀

 

Full Documentation: Eloquent Sluggable Package

 

Credit: Online illustrations by Storyset

Tinggalkan Komentar
Loading Comments