Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
166 lars 1
 
2
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/support-ukraine.svg?t=1" />](https://supportukrainenow.org)
3
 
4
# Generate slugs when saving Eloquent models
5
 
6
[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-sluggable.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-sluggable)
7
[![MIT Licensed](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)
8
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/spatie/laravel-sluggable/run-tests?label=tests)](https://github.com/spatie/laravel-sluggable/actions)
9
[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-sluggable.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-sluggable)
10
 
11
This package provides a trait that will generate a unique slug when saving any Eloquent model.
12
 
13
```php
14
$model = new EloquentModel();
15
$model->name = 'activerecord is awesome';
16
$model->save();
17
 
18
echo $model->slug; // outputs "activerecord-is-awesome"
19
```
20
 
21
The slugs are generated with Laravels `Str::slug` method, whereby spaces are converted to '-'.
22
 
23
Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects [on our website](https://spatie.be/opensource).
24
 
25
## Support us
26
 
27
[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/laravel-sluggable.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/laravel-sluggable)
28
 
29
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
30
 
31
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
32
 
33
## Installation
34
 
35
You can install the package via composer:
36
``` bash
37
composer require spatie/laravel-sluggable
38
```
39
 
40
## Usage
41
 
42
Your Eloquent models should use the `Spatie\Sluggable\HasSlug` trait and the `Spatie\Sluggable\SlugOptions` class.
43
 
44
The trait contains an abstract method `getSlugOptions()` that you must implement yourself.
45
 
46
Your models' migrations should have a field to save the generated slug to.
47
 
48
Here's an example of how to implement the trait:
49
 
50
```php
51
namespace App;
52
 
53
use Spatie\Sluggable\HasSlug;
54
use Spatie\Sluggable\SlugOptions;
55
use Illuminate\Database\Eloquent\Model;
56
 
57
class YourEloquentModel extends Model
58
{
59
    use HasSlug;
60
 
61
    /**
62
     * Get the options for generating the slug.
63
     */
64
    public function getSlugOptions() : SlugOptions
65
    {
66
        return SlugOptions::create()
67
            ->generateSlugsFrom('name')
68
            ->saveSlugsTo('slug');
69
    }
70
}
71
```
72
 
73
With its migration:
74
 
75
```php
76
use Illuminate\Database\Migrations\Migration;
77
use Illuminate\Database\Schema\Blueprint;
78
use Illuminate\Support\Facades\Schema;
79
 
80
class CreateYourEloquentModelTable extends Migration
81
{
82
    public function up()
83
    {
84
        Schema::create('your_eloquent_models', function (Blueprint $table) {
85
            $table->increments('id');
86
            $table->string('slug'); // Field name same as your `saveSlugsTo`
87
            $table->string('name');
88
            $table->timestamps();
89
        });
90
    }
91
}
92
 
93
```
94
 
95
### Using slugs in routes
96
 
97
To use the generated slug in routes, remember to use Laravel's [implicit route model binding](https://laravel.com/docs/5.8/routing#implicit-binding):
98
 
99
```php
100
namespace App;
101
 
102
use Spatie\Sluggable\HasSlug;
103
use Spatie\Sluggable\SlugOptions;
104
use Illuminate\Database\Eloquent\Model;
105
 
106
class YourEloquentModel extends Model
107
{
108
    use HasSlug;
109
 
110
    /**
111
     * Get the options for generating the slug.
112
     */
113
    public function getSlugOptions() : SlugOptions
114
    {
115
        return SlugOptions::create()
116
            ->generateSlugsFrom('name')
117
            ->saveSlugsTo('slug');
118
    }
119
 
120
    /**
121
     * Get the route key for the model.
122
     *
123
     * @return string
124
     */
125
    public function getRouteKeyName()
126
    {
127
        return 'slug';
128
    }
129
}
130
```
131
 
132
### Using multiple fields to create the slug
133
 
134
Want to use multiple field as the basis for a slug? No problem!
135
 
136
```php
137
public function getSlugOptions() : SlugOptions
138
{
139
    return SlugOptions::create()
140
        ->generateSlugsFrom(['first_name', 'last_name'])
141
        ->saveSlugsTo('slug');
142
}
143
```
144
 
145
### Customizing slug generation
146
 
147
You can also pass a `callable` to `generateSlugsFrom`.
148
 
149
By default the package will generate unique slugs by appending '-' and a number, to a slug that already exists.
150
 
151
You can disable this behaviour by calling `allowDuplicateSlugs`.
152
 
153
```php
154
public function getSlugOptions() : SlugOptions
155
{
156
    return SlugOptions::create()
157
        ->generateSlugsFrom('name')
158
        ->saveSlugsTo('slug')
159
        ->allowDuplicateSlugs();
160
}
161
```
162
 
163
### Limiting the length of a slug
164
 
165
You can also put a maximum size limit on the created slug:
166
 
167
```php
168
public function getSlugOptions() : SlugOptions
169
{
170
    return SlugOptions::create()
171
        ->generateSlugsFrom('name')
172
        ->saveSlugsTo('slug')
173
        ->slugsShouldBeNoLongerThan(50);
174
}
175
```
176
 
177
The slug may be slightly longer than the value specified, due to the suffix which is added to make it unique.
178
 
179
You can also use a custom separator by calling `usingSeparator`
180
 
181
```php
182
public function getSlugOptions() : SlugOptions
183
{
184
    return SlugOptions::create()
185
        ->generateSlugsFrom('name')
186
        ->saveSlugsTo('slug')
187
        ->usingSeparator('_');
188
}
189
```
190
 
191
### Setting the slug language
192
 
193
To set the language used by `Str::slug` you may call `usingLanguage`
194
 
195
```php
196
public function getSlugOptions() : SlugOptions
197
{
198
    return SlugOptions::create()
199
        ->generateSlugsFrom('name')
200
        ->saveSlugsTo('slug')
201
        ->usingLanguage('nl');
202
}
203
```
204
 
205
### Overriding slugs
206
 
207
You can also override the generated slug just by setting it to another value than the generated slug.
208
 
209
```php
210
$model = EloquentModel::create(['name' => 'my name']); //slug is now "my-name";
211
$model->slug = 'my-custom-url';
212
$model->save(); //slug is now "my-custom-url";
213
```
214
 
215
## Prevents slugs from being generated on some conditions
216
 
217
If you don't want to create the slug when the model has a state, you can use the `skipGenerateWhen` function.
218
 
219
```php
220
public function getSlugOptions() : SlugOptions
221
{
222
    return SlugOptions::create()
223
        ->generateSlugsFrom('name')
224
        ->saveSlugsTo('slug')
225
        ->skipGenerateWhen(fn () => $this->state === 'draft');
226
}
227
```
228
 
229
### Prevent slugs from being generated on creation
230
 
231
If you don't want to create the slug when the model is initially created you can set use the `doNotGenerateSlugsOnCreate()` function.
232
 
233
```php
234
public function getSlugOptions() : SlugOptions
235
{
236
    return SlugOptions::create()
237
        ->generateSlugsFrom('name')
238
        ->saveSlugsTo('slug')
239
        ->doNotGenerateSlugsOnCreate();
240
}
241
```
242
 
243
### Prevent slug updates
244
 
245
Similarly, if you want to prevent the slug from being updated on model updates, call `doNotGenerateSlugsOnUpdate()`.
246
 
247
```php
248
public function getSlugOptions() : SlugOptions
249
{
250
    return SlugOptions::create()
251
        ->generateSlugsFrom('name')
252
        ->saveSlugsTo('slug')
253
        ->doNotGenerateSlugsOnUpdate();
254
}
255
```
256
 
257
This can be helpful for creating permalinks that don't change until you explicitly want it to.
258
 
259
```php
260
$model = EloquentModel::create(['name' => 'my name']); //slug is now "my-name";
261
$model->save();
262
 
263
$model->name = 'changed name';
264
$model->save(); //slug stays "my-name"
265
```
266
 
267
### Regenerating slugs
268
 
269
If you want to explicitly update the slug on the model you can call `generateSlug()` on your model at any time to make the slug according to your other options. Don't forget to `save()` the model to persist the update to your database.
270
 
271
### Preventing overwrites
272
 
273
You can prevent slugs from being overwritten.
274
 
275
```php
276
public function getSlugOptions() : SlugOptions
277
{
278
    return SlugOptions::create()
279
        ->generateSlugsFrom('name')
280
        ->saveSlugsTo('slug')
281
        ->preventOverwrite();
282
}
283
```
284
 
285
### Using scopes
286
 
287
 
288
If you have a global scope that should be taken into account, you can define this as well with `extraScope`. For example if you have a pages table containing pages of multiple websites and every website has it's own unique slugs.
289
 
290
```php
291
public function getSlugOptions() : SlugOptions
292
{
293
    return SlugOptions::create()
294
        ->generateSlugsFrom('name')
295
        ->saveSlugsTo('slug')
296
        ->extraScope(fn ($builder) => $builder->where('scope_id', $this->scope_id));
297
}
298
```
299
 
300
### Setting the slug suffix starting index
301
 
302
By default, suffix index starts from 1, you can set starting number.
303
 
304
```php
305
public function getSlugOptions() : SlugOptions
306
{
307
    return SlugOptions::create()
308
        ->generateSlugsFrom('name')
309
        ->saveSlugsTo('slug')
310
        ->startSlugSuffixFrom(2);
311
}
312
```
313
 
314
### Integration with laravel-translatable
315
 
316
You can use this package along with [laravel-translatable](https://github.com/spatie/laravel-translatable) to generate a slug for each locale. Instead of using the `HasSlug` trait, you must use the `HasTranslatableSlug` trait, and add the name of the slug field to the `$translatable` array. For slugs that are generated from a single field _or_ multiple fields, you don't have to change anything else.
317
 
318
```php
319
namespace App;
320
 
321
use Spatie\Sluggable\HasTranslatableSlug;
322
use Spatie\Sluggable\SlugOptions;
323
use Spatie\Translatable\HasTranslations;
324
use Illuminate\Database\Eloquent\Model;
325
 
326
class YourEloquentModel extends Model
327
{
328
    use HasTranslations, HasTranslatableSlug;
329
 
330
    public $translatable = ['name', 'slug'];
331
 
332
    /**
333
     * Get the options for generating the slug.
334
     */
335
    public function getSlugOptions() : SlugOptions
336
    {
337
        return SlugOptions::create()
338
            ->generateSlugsFrom('name')
339
            ->saveSlugsTo('slug');
340
    }
341
}
342
```
343
 
344
For slugs that are generated from a callable, you need to instantiate the `SlugOptions` with the `createWithLocales` method. The callable now takes two arguments instead of one. Both the `$model` and the `$locale` are available to generate a slug from.
345
 
346
```php
347
namespace App;
348
 
349
use Spatie\Sluggable\HasTranslatableSlug;
350
use Spatie\Sluggable\SlugOptions;
351
use Spatie\Translatable\HasTranslations;
352
use Illuminate\Database\Eloquent\Model;
353
 
354
class YourEloquentModel extends Model
355
{
356
    use HasTranslations, HasTranslatableSlug;
357
 
358
    public $translatable = ['name', 'slug'];
359
 
360
    /**
361
     * Get the options for generating the slug.
362
     */
363
    public function getSlugOptions() : SlugOptions
364
    {
365
        return SlugOptions::createWithLocales(['en', 'nl'])
366
            ->generateSlugsFrom(function($model, $locale) {
367
                return "{$locale} {$model->id}";
368
            })
369
            ->saveSlugsTo('slug');
370
    }
371
}
372
 
373
```
374
 
375
#### Implicit route model binding
376
 
377
You can also use Laravels [implicit route model binding](https://laravel.com/docs/8.x/routing#implicit-binding) inside your controller to automatically resolve the model. To use this feature, make sure that the slug column matches the `routeNameKey`.
378
Currently, only some database types support JSON operations. Further information about which databases support JSON can be found in the [Laravel docs](https://laravel.com/docs/8.x/queries#json-where-clauses).
379
 
380
```php
381
namespace App;
382
 
383
use Spatie\Sluggable\HasSlug;
384
use Spatie\Sluggable\SlugOptions;
385
use Illuminate\Database\Eloquent\Model;
386
 
387
class YourEloquentModel extends Model
388
{
389
    use HasTranslations, HasTranslatableSlug;
390
 
391
    public $translatable = ['name', 'slug'];
392
 
393
    /**
394
     * Get the options for generating the slug.
395
     */
396
    public function getSlugOptions() : SlugOptions
397
    {
398
        return SlugOptions::create()
399
            ->generateSlugsFrom('name')
400
            ->saveSlugsTo('slug');
401
    }
402
 
403
    /**
404
     * Get the route key for the model.
405
     *
406
     * @return string
407
     */
408
    public function getRouteKeyName()
409
    {
410
        return 'slug';
411
    }
412
}
413
```
414
 
415
 
416
## Changelog
417
 
418
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
419
 
420
## Testing
421
 
422
``` bash
423
composer test
424
```
425
 
426
## Contributing
427
 
428
Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
429
 
430
## Security
431
 
432
If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.
433
 
434
## Credits
435
 
436
- [Freek Van der Herten](https://github.com/freekmurze)
437
- [All Contributors](../../contributors)
438
 
439
## License
440
 
441
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.