Slug ใน Laravel 8 แก้ปัญหาใช้ภาษาไทยไม่ได้ SEO Friendly urls

Posted by tospichai on May 25, 2021
profile
tospichai

Posted on May 25, 2021

#seo #laravel

Slug คือ ชื่อของ URL ของโพสต์นั้นๆ อาจจะมีหมวดหมู่ อยู่ด้านหน้าแล้วตามด้วยชื่อโพสต์ เช่น blog/การแก้ปัญหา-slug-ใน-laravel-8 โดยปกติแล้ว slug ใน laravel นั้นจะ Support กับภาษาอังกฤษ ทำให้ไม่แสดง slug ในภาษาไทย

ปัญหามีอยู่ว่าผมจะใช้ Slug อยากทำให้ SEO Friendly urls จึงลองใช้ Str::slug

วิธีแรกเลย ไม่น่ามีปัญหากับการค้นหา Row ของ id อย่างแน่นอน คือ เพิ่ม Slug ลงไปในฐานข้อมูลพร้อมกับข้อมูลนั้นๆเลย จะทำให้เราค้นหาได้เลย

    Model::Where('slug',$title)->first();

ทำให้เราใช้ฟังก์ชั่น Str::slug แค่ตอนลงข้อมูลเท่านั้น แต่หากมีการเปลี่ยนชื่อที่เราใช้ในการอ้างอิงกับ Slug ก็ต้องเขียนอัพเดตด้วย ผมจึงคิดว่าน่าจะมีวิธีที่ดีกว่านี้ แต่พอลองไม่เพิ่ม Slug ลงในฐานข้อมูล แต่อ้างอิงจากชื่อของโพสต์เลยกลับเกิดปัญหาว่า ภาษาไทยไม่แสดง กลับแสดงเป็นว่างๆ ส่วนภาษาอังกฤษเป็นปกติ แต่ว่า Str::slug มีพารามิเตอร์ในส่วนของภาษาอยู่จึงลองใช้

    @foreach($blog as $row)<a href="route("blog")/{{Str::slug($row->name,'th')}}">{{$row->name}}</a>@endforeach

ค่าที่ได้กลับเป็นคำภาษาอังกฤษที่อ่านเป็นไทย เศร้าใจจัง เอาล่ะต้องหาวิธีใหม่ นั้นก็คือ

แก้ Function Str::slug ซะเลย ซึ่งอยู่ใน

    \vendor\laravel\framework\src\Illuminate\Support\Str.php

เอาละเราเข้าไปแก้กันเลย

public static function slug($title, $separator = '-', $language = 'en'){
    $flip = $separator === '-' ? '_' : '-';
    $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
    $title = str_replace('@', $separator.'at'.$separator, $title);
    $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
return trim($title, $separator);}

ตัวแรกทำให้ภาษาไทยไม่แสดงค่า ตัวที่สองทำให้สระหาย ข้อแม้ ในชื่อนั้นห้ามใช้ - เนื่องจากเป็น slug ทำให้หาไม่เจอ หากใช้ค่า slug default

Login