Easy creation of slugs for your Eloquent models in Laravel

Overview

Eloquent-Sluggable

Easy creation of slugs for your Eloquent models in Laravel.

NOTE: These instructions are for the latest version of Laravel.
If you are using an older version, please install a version of the package that correlates to your Laravel version.

Build Status Total Downloads Latest Stable Version Latest Unstable Version SensioLabsInsight License

Background: What is a slug?

A slug is a simplified version of a string, typically URL-friendly. The act of "slugging" a string usually involves converting it to one case, and removing any non-URL-friendly characters (spaces, accented letters, ampersands, etc.). The resulting string can then be used as an identifier for a particular resource.

For example, if you have a blog with posts, you could refer to each post via the ID:

http://example.com/post/1
http://example.com/post/2

... but that's not particularly friendly (especially for SEO). You probably would prefer to use the post's title in the URL, but that becomes a problem if your post is titled "My Dinner With André & François", because this is pretty ugly too:

http://example.com/post/My+Dinner+With+Andr%C3%A9+%26+Fran%C3%A7ois

The solution is to create a slug for the title and use that instead. You might want to use Laravel's built-in Str::slug() method to convert that title into something friendlier:

http://example.com/post/my-dinner-with-andre-francois

A URL like that will make users happier (it's readable, easier to type, etc.).

For more information, you might want to read this description on Wikipedia.

Slugs tend to be unique as well. So if you write another post with the same title, you'd want to distinguish between them somehow, typically with an incremental counter added to the end of the slug:

http://example.com/post/my-dinner-with-andre-francois
http://example.com/post/my-dinner-with-andre-francois-1
http://example.com/post/my-dinner-with-andre-francois-2

This keeps the URLs unique.

The Eloquent-Sluggable package for Laravel aims to handle all of this for you automatically, with minimal configuration.

Installation

Depending on your version of Laravel, you should install a different version of the package.

NOTE: As of version 6.0, the package's version should match the Laravel version.

Laravel Version Package Version
8.0 ^8.0
7.0 ^7.0
6.0 ^6.0
5.8 4.8.*
5.7 4.6.*
5.6 4.5.*
5.5 4.3.*
5.4 4.2.*

Older versions of Laravel can use older versions of the package, although they are no longer supported or maintained. See CHANGELOG.md and UPGRADING.md for specifics, and be sure that you are reading the correct README.md for your version (Github displays the version in the master branch by default, which might not be what you want).

  1. Install the package via Composer:

    $ composer require cviebrock/eloquent-sluggable

    The package will automatically register its service provider.

  2. Optionally, publish the configuration file if you want to change any defaults:

    php artisan vendor:publish --provider="Cviebrock\EloquentSluggable\ServiceProvider"

Updating your Eloquent Models

Your models should use the Sluggable trait, which has an abstract method sluggable() that you need to define. This is where any model-specific configuration is set (see Configuration below for details):

use Cviebrock\EloquentSluggable\Sluggable;

class Post extends Model
{
    use Sluggable;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }
}

Of course, your model and database will need a column in which to store the slug. You can use slug or any other appropriate name you want; your configuration array will determine to which field the data will be stored. You will need to add the column (which should be NULLABLE) manually via your own migration.

That's it ... your model is now "sluggable"!

Usage

Saving a model is easy:

$post = Post::create([
    'title' => 'My Awesome Blog Post',
]);

So is retrieving the slug:

echo $post->slug;

NOTE: that if you are replicating your models using Eloquent's replicate() method, the package will automatically re-slug the model afterwards to ensure uniqueness.

$post = Post::create([
    'title' => 'My Awesome Blog Post',
]);
// $post->slug is "my-awesome-blog-post"

$newPost = $post->replicate();
// $newPost->slug is "my-awesome-blog-post-1"

NOTE: empty strings, non-strings or other "odd" source values will result in different slugs:

Source Value Resulting Slug
string string
empty string no slug will be set
null no slug will be set
0 "0"
1 "1"
false "0"
true "1"

(The above values would be subject to any unique or other checks as well.)

The SlugService Class

All the logic to generate slugs is handled by the \Cviebrock\EloquentSluggable\Services\SlugService class.

Generally, you don't need to access this class directly, although there is one static method that can be used to generate a slug for a given string without actually creating or saving an associated model.

use \Cviebrock\EloquentSluggable\Services\SlugService;

$slug = SlugService::createSlug(Post::class, 'slug', 'My First Post');

This would be useful for Ajax-y controllers or the like, where you want to show a user what the unique slug would be for a given test input, before actually creating a model. The first two arguments to the method are the model and slug field being tested, and the third argument is the source string to use for testing the slug.

You can also pass an optional array of configuration values as the fourth argument. These will take precedence over the normal configuration values for the slug field being tested. For example, if your model is configured to use unique slugs, but you want to generate the "base" version of a slug for some reason, you could do:

$slug = SlugService::createSlug(Post::class, 'slug', 'My First Post', ['unique' => false]);

When Is A Model Slugged?

Currently, the model is slugged on Eloquent's saving event. This means that the slug is generated before any new data is written to the database.

For new models, this means that the primary key has not yet been set, so it could not be used as part of the slug source, e.g.:

public function sluggable(): array
{
    return [
        'slug' => [
            'source' => ['title', 'id']
        ]
    ];
}

$model->id is null before the model is saved. The benefit of hooking into the saving event, however, is that we only needed to make one database query to save all the model's data, including the slug.

Optional, the model can be slugged on Eloquent's saved event.
This means that all the other model attributes will have already been persisted to the database and are available for use as slug sources. So the above configuration would work. The only drawback is that saving the model to the database requires one extra query: the first one to save all the non-slug fields, and then a second one to update just the slug field.

This behaviour is a breaking change, and likely won't affect most users (unless you are doing some pre-saving validation on a model's slug field). We feel the benefits outweigh the drawbacks, and so this will likely become the new default behaviour in a future major release of the package. Although, to make the transition easier, you can configure this behaviour via the sluggableEvent method the trait provides:

    public function sluggableEvent(): string
    {
        /**
         * Default behaviour -- generate slug before model is saved.
         */
        return SluggableObserver::SAVING;

        /**
         * Optional behaviour -- generate slug after model is saved.
         * This will likely become the new default in the next major release.
         */
        return SluggableObserver::SAVED;
    }

Keep in mind that you will need to use SluggableObserver::SAVED if you want to use your model's primary key as part of the source fields for your slugs.

Events

NOTE: Events should be working but are not fully tested yet. Please help me out!

Sluggable models will fire two Eloquent model events: "slugging" and "slugged".

The "slugging" event is fired just before the slug is generated. If the callback from this event returns false, then the slugging is not performed. If anything else is returned, including null, then the slugging will be performed.

The "slugged" event is fired just after a slug is generated. It won't be called in the case where the model doesn't need slugging (as determined by the needsSlugging() method).

You can hook into either of these events just like any other Eloquent model event:

Post::registerModelEvent('slugging', static function($post) {
    if ($post->someCondition()) {
        // the model won't be slugged
        return false;
    }
});

Post::registerModelEvent('slugged', static function($post) {
    Log::info('Post slugged: ' . $post->getSlug());
});

Configuration

Configuration was designed to be as flexible as possible. You can set up defaults for all of your Eloquent models, and then override those settings for individual models.

By default, global configuration is set in the config/sluggable.php file. If a configuration isn't set, then the package defaults are used. Here is an example configuration, with all the default settings shown:

return [
    'source'             => null,
    'method'             => null,
    'onUpdate'           => false,
    'separator'          => '-',
    'unique'             => true,
    'uniqueSuffix'       => null,
    'firstUniqueSuffix'  => 2,
    'includeTrashed'     => false,
    'reserved'           => null,
    'maxLength'          => null,
    'maxLengthKeepWords' => true,
    'slugEngineOptions'  => [],
];

For individual models, configuration is handled in the sluggable() method that you need to implement. That method should return an indexed array where the keys represent the fields where the slug value is stored and the values are the configuration for that field. This means you can create multiple slugs for the same model, based on different source strings and with different configuration options.

public function sluggable(): array
{
    return [
        'title-slug' => [
            'source' => 'title'
        ],
        'author-slug' => [
            'source' => ['author.lastname', 'author.firstname'],
            'separator' => '_'
        ],
    ];
}

source

This is the field or array of fields from which to build the slug. Each $model->field is concatenated (with space separation) to build the sluggable string. These can be model attributes (i.e. fields in the database), relationship attributes, or custom getters.

To reference fields from related models, use dot-notation. For example, the slug for the following book will be generated from its author's name and the book's title:

class Book extends Eloquent
{
    use Sluggable;

    protected $fillable = ['title'];

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => ['author.name', 'title']
            ]
        ];
    }
    
    public function author(): \Illuminate\Database\Eloquent\Relations\BelongsTo
    {
        return $this->belongsTo(Author::class);
    }
}
...
class Author extends Eloquent
{
    protected $fillable = ['name'];
}

An example using a custom getter:

class Person extends Eloquent
{
    use Sluggable;

    public function sluggable(): array
    {
        return [
            'slug' => [
                'source' => 'fullname'
            ]
        ];
    }

    public function getFullnameAttribute(): string
    {
        return $this->firstname . ' ' . $this->lastname;
    }
}

If source is empty, false or null, then the value of $model->__toString() is used as the source for slug generation.

method

Defines the method used to turn the sluggable string into a slug. There are three possible options for this configuration:

  1. When method is null (the default setting), the package uses the default slugging engine -- cocur/slugify -- to create the slug.

  2. When method is a callable, then that function or class method is used. The function/method should expect two parameters: the string to process, and a separator string. For example, to use Laravel's Str::slug, you could do:

'method' => ['Illuminate\\Support\\Str', 'slug'],
  1. You can also define method as a closure (again, expecting two parameters):
'method' => static function(string $string, string $separator): string {
    return strtolower(preg_replace('/[^a-z]+/i', $separator, $string));
},

Any other values for method will throw an exception.

For more complex slugging requirements, see Extending Sluggable below.

onUpdate

By default, updating a model will not try and generate a new slug value. It is assumed that once your slug is generated, you won't want it to change (this may be especially true if you are using slugs for URLs and don't want to mess up your SEO mojo).

If you want to regenerate one or more of your model's slug fields, you can set those fields to null or an empty string before the update:

$post->slug = null;
$post->update(['title' => 'My New Title']);

If this is the behaviour you want every time you update a model, then set the onUpdate option to true.

separator

This defines the separator used when building a slug, and is passed to the method defined above. The default value is a hyphen.

unique

This is a boolean defining whether slugs should be unique among all models of the given type. For example, if you have two blog posts and both are called "My Blog Post", then they will both sluggify to "my-blog-post" if unique is false. This could be a problem, e.g. if you use the slug in URLs.

By setting unique to true, then the second Post model will sluggify to "my-blog-post-1". If there is a third post with the same title, it will sluggify to "my-blog-post-2" and so on. Each subsequent model will get an incremental value appended to the end of the slug, ensuring uniqueness.

uniqueSuffix

If you want to use a different way of identifying uniqueness (other than auto-incrementing integers), you can set the uniqueSuffix configuration to a function or callable that generates the "unique" values for you.

The function should take four parameters:

  1. the base slug (i.e. the non-unique slug)
  2. the separator string
  3. an \Illuminate\Support\Collection of all the other slug strings that start with the same slug
  4. the first suffix to use (for the first slug that needs to be made unique) You can then do whatever you want to create a new suffix that hasn't been used by any of the slugs in the collection. For example, if you wanted to use letters instead of numbers as a suffix, this is one way to achieve that:
'uniqueSuffix' => static function(string $slug, string $separator, Collection $list, $firstSuffix): string
    {
      $size = count($list);

      return chr($size + 96);
    }

firstUniqueSuffix

When adding a unique suffix, we start counting at "2", so that the list of generated slugs would look something like:

  • my-unique-slug
  • my-unique-slug-2
  • my-unique-slug-3
  • etc.

If you want to start counting at a different number (or pass a different value into your custom uniqueSuffix function above), then you can define it here.

NOTE: Prior versions of the package started with a unique suffix of 1. This was switched to 2 in version 8.0.5, as it's a more "intuitive" suffix value to attach to the second slug.

includeTrashed

Setting this to true will also check deleted models when trying to enforce uniqueness. This only affects Eloquent models that are using the softDelete feature. Default is false, so soft-deleted models don't count when checking for uniqueness.

reserved

An array of values that will never be allowed as slugs, e.g. to prevent collisions with existing routes or controller methods, etc.. This can be an array, or a closure that returns an array. Defaults to null: no reserved slug names.

maxLength

Setting this to a positive integer will ensure that your generated slugs are restricted to a maximum length (e.g. to ensure that they fit within your database fields). By default, this value is null and no limit is enforced.

NOTE: If unique is enabled (which it is by default), and you anticipate having several models with the same slug, then you should set this value to a few characters less than the length of your database field. The reason why is that the class will append "-2", "-3", "-4", etc., to subsequent models in order to maintain uniqueness. These incremental extensions aren't included in part of the maxLength calculation.

maxLengthKeepWords

If you are truncating your slugs with the maxLength setting, than you probably want to ensure that your slugs don't get truncated in the middle of a word. For example, if your source string is "My First Post", and your maxLength is 10, the generated slug would end up being "my-first-p", which isn't ideal.

By default, the maxLengthKeepWords value is set to true which would trim the partial words off the end of the slug, resulting in "my-first" instead of "my-first-p".

If you want to keep partial words, then set this configuration to false.

slugEngineOptions

When method is null (the default setting), the package uses the default slugging engine -- cocur/slugify -- to create the slug. If you want to pass a custom set of options to the Slugify constructor when the engine is instantiated, this is where you would define that. See the documentation for Slugify for what those options are. Also, look at customizeSlugEngine for other ways to customize Slugify for slugging.

Short Configuration

The package supports a really short configuration syntax, if you are truly lazy:

public function sluggable(): array
{
    return ['slug'];
}

This will use all the default options from config/sluggable.php, use the model's __toString() method as the source, and store the slug in the slug field.

Extending Sluggable

Sometimes the configuration options aren't sufficient for complex needs (e.g. maybe the uniqueness test needs to take other attributes into account).

In instances like these, the package offers hooks into the slugging workflow where you can use your own functions, either on a per-model basis, or in your own trait that extends the package's trait.

NOTE: If you are putting these methods into your own trait, you will need to indicate in your models that PHP should use your trait methods instead of the packages (since a class can't use two traits with the same methods), e.g.

/**
 * Your trait where you collect your common Sluggable extension methods
 */
class MySluggableTrait {
    public function customizeSlugEngine(...) {}
    public function scopeWithUniqueSlugConstraints(...) {}
    // etc.
}

/**
 * Your model
 */
class MyModel {
    // Tell PHP to use your methods instead of the packages:
    use Sluggable,
        MySluggableTrait  {
            MySluggableTrait::customizeSlugEngine insteadof Sluggable;
            MySluggableTrait::scopeWithUniqueSlugConstraints insteadof Sluggable;
        }

    // ...
}

customizeSlugEngine

/**
 * @param \Cocur\Slugify\Slugify $engine
 * @param string $attribute
 * @return \Cocur\Slugify\Slugify
 */
public function customizeSlugEngine(Slugify $engine, string $attribute): \Cocur\Slugify\Slugify
{
    // ...
    return $engine;
}

If you extend this method, the Slugify engine can be customized before slugging occurs. This might be where you change the character mappings that are used, or alter language files, etc..

You can customize the engine on a per-model and per-attribute basis (maybe your model has two slug fields, and one of them needs customization).

Take a look at tests/Models/PostWithCustomEngine.php for an example.

Also, take a look at the slugEngineOptions configuration for other ways to customize Slugify.

scopeWithUniqueSlugConstraints

/**
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @param \Illuminate\Database\Eloquent\Model $model
 * @param string $attribute
 * @param array $config
 * @param string $slug
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeWithUniqueSlugConstraints(
    Builder $query,
    Model $model,
    string $attribute,
    array $config,
    string $slug
): Builder
{
    // ...
}

This method is applied to the query that is used to determine if a given slug is unique. The arguments passed to the scope are:

  • $model -- the object being slugged
  • $attribute -- the slug field being generated,
  • $config -- the configuration array for the given model and attribute
  • $slug -- the "base" slug (before any unique suffixes are applied)

Feel free to use these values anyway you like in your query scope. As an example, look at tests/Models/PostWithUniqueSlugConstraints.php where the slug is generated for a post from it's title, but the slug is scoped to the author. So Bob can have a post with the same title as Pam's post, but both will have the same slug.

scopeFindSimilarSlugs

/**
 * Query scope for finding "similar" slugs, used to determine uniqueness.
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @param string $attribute
 * @param array $config
 * @param string $slug
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeFindSimilarSlugs(Builder $query, string $attribute, array $config, string $slug): Builder
{
    // ...
}

This is the default scope for finding "similar" slugs for a model. Basically, the package looks for existing slugs that are the same as the $slug argument, or that start with $slug plus the separator string. The resulting collection is what is passed to the uniqueSuffix handler.

Generally, this query scope (which is defined in the Sluggable trait) should be left alone. However, you are free to overload it in your models.

SluggableScopeHelpers Trait

Adding the optional SluggableScopeHelpers trait to your model allows you to work with models and their slugs. For example:

$post = Post::whereSlug($slugString)->get();

$post = Post::findBySlug($slugString);

$post = Post::findBySlugOrFail($slugString);

Because models can have more than one slug, this requires a bit more configuration. See SCOPE-HELPERS.md for all the details.

Route Model Binding

See ROUTE-MODEL-BINDING.md for details.

Bugs, Suggestions, Contributions and Support

Thanks to everyone who has contributed to this project! Special thanks to JetBrains for their Open Source License Program ... and the excellent PHPStorm IDE, of course!

JetBrains

Please use Github for reporting bugs, and making comments or suggestions.

See CONTRIBUTING.md for how to contribute changes.

Copyright and License

eloquent-sluggable was written by Colin Viebrock and is released under the MIT License.

Copyright (c) 2013 Colin Viebrock

Comments
  • strpos(): Empty needle

    strpos(): Empty needle

    some times i get this error:

    /home
    /admin
    /domains
    /mydomain
    /vendor
    /cviebrock
    /eloquent-sluggable
    /src
    /Services
    /SlugService.php
    
                //     a) the list is empty, or
                //     b) our slug isn't in the list
                // ... we are okay
                if (
                    $list->count() === 0 ||
                    $list->contains($slug) === false
                ) {
                    return $slug;
                }
         
                // if our slug is in the list, but
                //     a) it's for our model, or
                //  b) it looks like a suffixed version of our slug
                // ... we are also okay (use the current slug)
                if ($list->has($this->model->getKey())) {
                    $currentSlug = $list->get($this->model->getKey());
         
                    if (
                        $currentSlug === $slug ||
                        strpos($currentSlug, $slug) === 0
                    ) {
                        return $currentSlug;
                    }
                }
         
                $method = $config['uniqueSuffix'];
                if ($method === null) {
                    $suffix = $this->generateSuffix($slug, $separator, $list);
                } elseif (is_callable($method)) {
                    $suffix = $method($slug, $separator, $list);
                } else {
                    throw new \UnexpectedValueException('Sluggable "uniqueSuffix" for '.get_class($this->model).':'.$attribute.' is not null, or a closure.');
                }
         
                return $slug.$separator.$suffix;
            }
         
            /**
             * Generate a unique suffix for the given slug (and list of existing, "similar" slugs.
             *
    
    Arguments
    
        "strpos(): Empty needle"
    
    
    opened by pishguy 25
  • ErrorException array_merge(): Argument #1 is not an array when saving a model Laravel 5.4

    ErrorException array_merge(): Argument #1 is not an array when saving a model Laravel 5.4

    I upgraded a Laravel app from 4.2 to 5.4 that was using eloquent-sluggable. I setup a fresh Laravel app and migrated over the controllers, views, etc. I'm having an issue with eloquent-sluggable.

    I followed the E-S upgrade guide and updated the Models to the latest recommendations.

    I get this error when eloquent is saving a model.

    [2017-09-13 22:44:28] local.ERROR: ErrorException: array_merge(): Argument #1 is not an array in /Users/underwood/code/valet/project/vendor/cviebrock/eloquent-sluggable/src/Services/SlugService.php:65

    App is L5.4, PHP 7 cviebrock/eloquent-sluggable 4.2.5

    opened by underwood 24
  • Make compatible with Laravel 5.2

    Make compatible with Laravel 5.2

    According to the upgrade guide

    The Illuminate\Foundation\Support\Composer class has been moved to Illuminate\Support\Composer. This is unlikely to affect your application if you were not manually using this class.

    opened by nivv 20
  • Slugging after save problems

    Slugging after save problems

    This recent change caused a serious BC breakage for me related to pre-save model validation. I also question whether it's a good idea from a performance standpoint, since it adds another roundtrip to the database every time a model is saved.

    Can this be configurable instead? I would think the default behavior should be to generate the slug prior to saving, but a config setting could allow that to be overridden if necessary.

    I can produce a PR for this if you'd like @cviebrock.

    bug triaged 
    opened by adamthehutt 16
  • Support Laravel 5.2

    Support Laravel 5.2

    Laravel 5.1 deprecated using bindShared and 5.2 removed it completely, because of this a package update to cocur/slugify is needed to at least 1.4. orchestra/testbench 3.0 only supports Laravel 5.0.* so that requires an update as well.

    Illuminate\Foundation\Composer has been moved to Illuminate\Support\Composer

    opened by EspadaV8 15
  • phpunit acceptance tests using a model with sluggable failing

    phpunit acceptance tests using a model with sluggable failing

    Attempting to write an acceptable test using a model that includes sluggable, getting the following error message. It's failing during the setUp function.

      public function setUp(){
        $user = User::create([
          'first_name' => 'Admin',
          'last_name' => 'User',
          'email' => '[email protected]',
        ]);
    
        $role = Role::create([
          'name' => 'Admin',
          'slug' => 'admin',
          'description' => 'An Admin'
        ]);
        $role->save();
        $user->attach($role);
      }
    
    

    And the error

    
    1) EditUserTest::test_add_property_function
    Illuminate\Contracts\Container\BindingResolutionException: Target [Illuminate\Contracts\Events\Dispatcher] is not instantiable while building [Cviebrock\EloquentSluggable\SluggableObserver].
    
    

    The error occurs on line that creates the user, which is the model that includes sluggable. Removing that step gets rid of the error (though obviously causes a new one as there is no user to attach the role too).

    If this isn't enough information let me know, wasn't really sure what else to include

    Laravel version 5.3, sluggable 4.1, phpunit 5.7.20

    opened by ajoy39 14
  • eloquent-sluggable with Laravel 5.3

    eloquent-sluggable with Laravel 5.3

    Is it me or does eloquent-sluggable not work with Laravel 5.3. I just updated my project from 5.2 to 5.3 and it seems that models are empty when loading a page which get the model through the slug from the route.

    opened by dees040 14
  • Generate slug for existing records

    Generate slug for existing records

    Right now it only creates a migration. Would be nice to have a command that creates slugs for existing records in that table. Even nicer with a --seed flag that also creates a seed file for it.

    opened by dan-klasson 14
  • PHP 7.4.1 issues

    PHP 7.4.1 issues

    ErrorException implode(): Passing glue string after array is deprecated. Swap the parameters

    Illuminate\Foundation\Bootstrap\HandleExceptions::handleError :141 C:\xampp\htdocs\foodcash\vendor\cviebrock\eloquent-sluggable\src\Services\SlugService.php:141

    opened by PeterNdeke 12
  • Unique slugs for all models in the project

    Unique slugs for all models in the project

    I need to ensure the uniqueness of the slugs throughout the project.

    I have some tables - blogs, posts, users, cities, etc. How about add config option, where you can list all the tables in which you should ensure the uniqueness of the slug. Example: tables = ['users','posts','cities'];

    What do you think about this feature?

    enhancement 
    opened by php-rock 12
  • Replicate method conflit

    Replicate method conflit

    Greetings,

    The replicate() method conflicts with the same method in sofa/eloquence -

    Trait method replicate has not been applied, because there are collisions with other trait methods on App\Skill
    

    Really need both packages. Ideas?

    opened by opheliadesign 12
Owner
Colin Viebrock
Colin Viebrock
An opinionated package to create slugs for Eloquent models

Generate slugs when saving Eloquent models This package provides a trait that will generate a unique slug when saving any Eloquent model. $model = new

Spatie 1.1k Jan 4, 2023
Simple slugs for your Laravel models.

Simple slugs for your Laravel models. This packages provides an opinionated, attribute-driven trait for automatically generating slugs when creating L

Ryan Chandler 20 Aug 15, 2022
A simple drop-in solution for providing UUID support for the IDs of your Eloquent models.

Introduction A simple drop-in solution for providing UUID support for the IDs of your Eloquent models. Both v1 and v4 IDs are supported out of the box

GoldSpec Digital 501 Jan 4, 2023
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.5k Jan 7, 2023
Automatically validating Eloquent models for Laravel

Validating, a validation trait for Laravel Validating is a trait for Laravel Eloquent models which ensures that models meet their validation criteria

Dwight Watson 955 Dec 25, 2022
Laravel Ban simplify blocking and banning Eloquent models.

Laravel Ban Introduction Laravel Ban simplify management of Eloquent model's ban. Make any model bannable in a minutes! Use case is not limited to Use

cybercog 879 Dec 30, 2022
cybercog 996 Dec 28, 2022
Tag support for Laravel Eloquent models - Taggable Trait

Laravel Taggable Trait This package is not meant to handle javascript or html in any way. This package handles database storage and read/writes only.

Rob 859 Dec 11, 2022
Preferences for Laravel Eloquent models

Preferences for Laravel Eloquent models Use this library to bind multiple key/value pair preferences to your application's Eloquent models. Preference

Kevin Laude 32 Oct 30, 2022
Laravel package to search through multiple Eloquent models.

Laravel package to search through multiple Eloquent models. Supports sorting, pagination, scoped queries, eager load relationships and searching through single or multiple columns.

Protone Media 845 Jan 1, 2023
Automatic human timestamps for Laravel Eloquent models.

Automatic human timestamp properties in Laravel This package provides a trait you can add to an Eloquent model that will automatically create human-re

Christopher Di Carlo 25 Jul 17, 2022
An Eloquent Way To Filter Laravel Models And Their Relationships

Eloquent Filter An Eloquent way to filter Eloquent Models and their relationships Introduction Lets say we want to return a list of users filtered by

Eric Tucker 1.5k Dec 30, 2022
🕵️ Inspect Laravel Eloquent models to collect properties, relationships and more.

??️ Eloquent Inspector Inspect Laravel Eloquent models to collect properties, relationships and more. Install Via Composer composer require cerbero/el

Andrea Marco Sartori 111 Nov 4, 2022
Laravel Nova Ban simplify blocking and banning Eloquent models.

Laravel Nova Ban Introduction Behind the scenes cybercog/laravel-ban is used. Contents Installation Usage Prepare bannable model Prepare bannable mode

cybercog 39 Sep 29, 2022
Package with small support traits and classes for the Laravel Eloquent models

Contains a set of traits for the eloquent model. In future can contain more set of classes/traits for the eloquent database.

Martin Kluska 3 Feb 10, 2022
Allow your model to record the creation, update and deletion of user fingerprints in laravel packages

This laravel package will allow your models to record the the created, updated and deleted by User FingerPrints

Managemize 4 Mar 11, 2022
Sortable behaviour for Eloquent models

Sortable behaviour for Eloquent models This package provides a trait that adds sortable behaviour to an Eloquent model. The value of the order column

Spatie 1.2k Dec 22, 2022
This package gives Eloquent models the ability to manage their friendships.

Laravel 5 Friendships This package gives Eloquent models the ability to manage their friendships. You can easily design a Facebook like Friend System.

Alex Kyriakidis 690 Nov 27, 2022
Create presenters for Eloquent Models

Laravel Presentable This package allows the information to be presented in a different way by means of methods that can be defined in the model's pres

The Hive Team 67 Dec 7, 2022