برای داشتن urlهای تمیز و SEO Friendly در برنامههای تحت وب راههای زیادی وجود داره. در لاراول به صورت پیشفرض میتونید به روش زیر slug یا نامک از رشتههاتون درست کنید:
$title = "sample title"; $slug = Str::slug($title); //output: sample-slug
کار خیلی راحتیه ولی هر سری که بخواهیم یک رکورد رو آپدیت یا ایجاد کنیم مجبوریم از این روش استفاده کنیم، ولی خب لاراول یه سری رویداد داره که میتونیم به صورت اتوماتیک این فیلد رو پر کنیم و نگران چیز دیگهای نباشیم. از اون راحتتر استفاده از Packageهای تست شده و آمادهست.
Eloqunet Sluggable یک پیکج برای تولید تولید اتوماتیک slug در لاراول میباشد که میتونید با مراجعه به صفحه گیتهاب این پکیج با اون روش نصبش آشنا بشید.
بعد از نصب و ایجاد تنظیمات مربوطه میتونید توی مدلهاتون ازش استفاده کنید . روش کار هم به این صورته که شما به طور فرض یک مدل دارید با نام Post. خب باید مدلتون یه چیزی شبیه زیر باشه:
class Post extends ٍEloquent { protected $table = 'posts'; }
بعد از نصب پکیج مربوطه فقط کافیه مدلتونو به شکل زیر تغییر بدید:
use CviebrockEloquentSluggableSluggableInterface; use CviebrockEloquentSluggableSluggableTrait; class Post extends Eloquent implements SluggableInterface { use SluggableTrait; protected $sluggable = array( 'build_from' => 'title',//فیلدی که slug از اون ساخته میشه 'save_to' => 'slug',//فیلدی که قراره خروجی slug در اون ذخیره بشه ); protected $table = 'posts'; }
بعد از انجام کارهای بالا حالا دیگه شما به راحتی پس از ایجاد یک پست جدید و انتخاب یک عنوان، slug اون رو هم به صورت اتوماتیک داشته باشید. مثلا:
$post = new Post; $post->title = 'hello world'; $post->save();
خب تا اینجای کار، همه چیز مرتبه ولی یه مشکل بزرگ وجود داره و اون هم عدم پشتیبانی این پکیج و متد Str::slug() از زبانهای یونیکد مثل فارسیه و این یعنی این پکیج و متد به درد ما نمیخورن. ولی باز هم راه حل وجود داره که به این ترتیبه:
ابتدا تنظیمات پکیج را publish میکنیم تا از فولدر config پروژهمون بهش دسترسی داشته باشیم و در هنگام بهروزرسانی پکیج، تنظیماتمون باقی بمونه. برای این کار دستور زیر رو توی ترمینال و در دایرکتوری ریشه پروژهتون وارد کنید:
php artisan config:publish cviebrock/eloquent-sluggable
حالا اگه به فولدر app/config/packages/cviebrock/eloquent-sluggable برید فایل تنظیمات با نام config.php اونجا قرار داره.
حالا اگه فایل تنظیماتو باز کنید میبینید که گزینههای مختلفی برای اعمال کردن داره مثل unique که مشخص میکنید که slugهاتون در دیتابیس یکتا باشند یا نه که یکتا بودنشون تو آدرسدهی میتونه خیلی کمک کنه و یا گزینه on_update که مشخص میکنید آیا نامک در هنگام به روزرسانی رکورد به روزرسانی بشه یا نه که پیشنهاد میکنم اینو به true تغییر بدید.
یک گزینه دیگر وجود داره به نام method که میتونید در این گزینه متد و یا تابع دلخواهی که میخواهید slugهاتون بر اساس اون ساخته بشن رو تعریف کنید. به صورت پیشفرض Eloquent-sluggable از متد Str::slug() برا ساختن نامک استفاده میکنه که مشکلشو با زبان فارسی فهمیدیم چیه.
برای پشتیبانی از زبانهای یونیکد فقط کافیه که متد زیر را به اون گزینه نسبت بدید و فایل config.php رو save کنید. بعد از اون به راحتی میتونید برید دنبال بقیه کارهاتون
'method' => function($string, $separator = '-') { $_transliteration = array( '/ä|æ|ǽ/' => 'ae', '/ö|œ/' => 'oe', '/ü/' => 'ue', '/Ä/' => 'Ae', '/Ü/' => 'Ue', '/Ö/' => 'Oe', '/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A', '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a', '/Ç|Ć|Ĉ|Ċ|Č/' => 'C', '/ç|ć|ĉ|ċ|č/' => 'c', '/Ð|Ď|Đ/' => 'D', '/ð|ď|đ/' => 'd', '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E', '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e', '/Ĝ|Ğ|Ġ|Ģ/' => 'G', '/ĝ|ğ|ġ|ģ/' => 'g', '/Ĥ|Ħ/' => 'H', '/ĥ|ħ/' => 'h', '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I', '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i', '/Ĵ/' => 'J', '/ĵ/' => 'j', '/Ķ/' => 'K', '/ķ/' => 'k', '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L', '/ĺ|ļ|ľ|ŀ|ł/' => 'l', '/Ñ|Ń|Ņ|Ň/' => 'N', '/ñ|ń|ņ|ň|ʼn/' => 'n', '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O', '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o', '/Ŕ|Ŗ|Ř/' => 'R', '/ŕ|ŗ|ř/' => 'r', '/Ś|Ŝ|Ş|Ș|Š/' => 'S', '/ś|ŝ|ş|ș|š|ſ/' => 's', '/Ţ|Ț|Ť|Ŧ/' => 'T', '/ţ|ț|ť|ŧ/' => 't', '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U', '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u', '/Ý|Ÿ|Ŷ/' => 'Y', '/ý|ÿ|ŷ/' => 'y', '/Ŵ/' => 'W', '/ŵ/' => 'w', '/Ź|Ż|Ž/' => 'Z', '/ź|ż|ž/' => 'z', '/Æ|Ǽ/' => 'AE', '/ß/' => 'ss', '/IJ/' => 'IJ', '/ij/' => 'ij', '/Œ/' => 'OE', '/ƒ/' => 'f' ); $quotedReplacement = preg_quote($separator, '/'); $merge = array( '/[^sp{Zs}p{Ll}p{Lm}p{Lo}p{Lt}p{Lu}p{Nd}]/mu' => ' ', '/[sp{Zs}]+/mu' => $separator, sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '', ); $map = $_transliteration + $merge; unset($_transliteration); return preg_replace(array_keys($map), array_values($map), $string); },
اینو بگم که من این متد رو از یکی از کتابخونههای فریمورک CakePHP برداشتم و با کمی تغییر تو اینجا قابل استفادهش کردم.