L
L
lolrofl012021-04-04 13:44:20
Laravel
lolrofl01, 2021-04-04 13:44:20

How are slugs formed in laravel?

It is necessary to immediately form a slug in the admin panel when entering a title. There are several such pages, because the types are different (categories, pages, posts, products, users, etc.). It seems nothing complicated, I do slugs through Str:slug. But, I don't want to write the same thing in every controller/model. Therefore, I create a separate class - slug generator. Class structure:

class SlugController extends Controller
{
    public function generate($phrase, $limit = 255)
    {
        $slug = Str::slug($phrase);
        if( strlen($slug) > $limit ) return Str::substr($slug, 0, $limit);
        else return $slug;
    }

    public function isUniq($table, $field, $slug)
    {
        $result = $table->where($field, $slug)->first();
        if(! $result ) return true;

        return false;
    }

    public function generateUniqSlug($table, $phrase, $limit)
    {
        $slug = $this->generate($phrase, $limit);
        if( $this->isUniq($table, $field, $slug) ) return $slug;
        else {
            for($i = 1; $i < 200; $i++) {
                $newSlug = $slug . '-' . $i;
                if( $this->isUniq($table, $field, $slug) ) return $newSlug;
            }
        }
    }

}


For some reason, there is a feeling that this is a terrible shit code, the invention of a bicycle and did not go there at all. But here's what you need:
1) Generation of the slug on the fly, just entered the title - the slug came right away. This slug must be unique
2) The user can change the slug, it is advisable to immediately check it thanks to the Ajax request, and notify if the slug is not unique
3) I don’t want to write the same checks in each controller, so I separated it into a separate class, but I do not like that in the function it is necessary to pass the model (table) and the field by which it is necessary to search for a unique slug or not.

Now they will say - there is Laravel sluggable. There is, but it seems to work in models when saving / updating. He does not give a choice, if the slug is not unique, he will immediately save it as slug-1 and will not ask. Plus, I'm not sure that it can be accessed simply to form an Ajax slug. Maybe you can, but it makes sense if there is Str::slug().

In general, tell me, good people, who can do what))

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Sklyarov, 2021-04-04
@lolrofl01

You can validate the data that comes to the controller through custom Request classes . There you can specify the following structure:

public function rules()
    {
        return [
            'slug' => [
                'string',
                'unique:posts,slug'
            ],
        ];
    }

If, when checking the Slug, it is already in the database, then a validation error is displayed. In order for the slug to be generated on the fly, you can implement the method
in the same custom Request :
protected function prepareForValidation() :void
    {
        $this->merge([
            'slug' => ($this->slug) ?? \Str::slug($this->title, '-')
        ]);
    }

That is, just before the validation of your data, the slug generated from the header will be added to this data, if the field is left empty, or the slug that you specified

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question