Tailor unique slug

Hi,

is there a way to have a unique (default field) slug in Tailor structure?

I have tried to force validation (as in docs for custom fields), but it is not working for default fields (works for existing records but not new).

Jan

@daft Hi Sam, have you any tips, ho to make slug unique with Tailor?

If anyone fights the same problem with unique (built-in tailor) field:

  1. Create plugin like php artisan plugin:create JanVince.TailorTools

  2. Add an event listener to plugin’s Plugin.php file in method boot():

Use your Tailor blueprint handles, I have Product\Category here.

        \Tailor\Models\EntryRecord::extendInSection('Product\Category', function($model) {
            $model->bindEvent('model.beforeCreate', function () use ($model) {

                $sameSlugItems = EntryRecord::inSection('Product\Category')->where('slug', $model->slug)->get();

                if($sameSlugItems and $sameSlugItems->count()) {
                    throw new \ValidationException(['slug' => 'URL is used!']);
                }

            });
        });

I don’t like creating plugin just for a simple validation but haven’t found a better way yet.

But it works :slight_smile:

4 Likes

Or you can do it with simplier solution in blueprints

fields:
    slug:
        type: text
        validation:
            - unique
1 Like

This is a good workaround ^^

We need a unique rule for this that is site-aware. Something like this

unique_site:email

As a modified version of the unique rule, internally it would look like this:

unique:users,email,NULL,id,site_root_id,<current site id>

I’ve made a note of this in our internal tracker.

1 Like

A site_unique rule has been added in v3.7.6 onwards.

The slug in Tailor records also implements this rule by default. It can be removed with the following

fields:
    slug:
        type: text
        validation:
            - required
1 Like

Hello,

I found this post by looking for a problem we have since 3.7.6 on our site where we get plenty of “Field slug is required” errors where we didn’t have any before. I think I found out why…

Can I ask why this field is suddenly required by default?

I was going to temporarily modify the modules/tailor/models/EntryRecord.php file to remove the slug from the $rules attribute like so:

 /**
     * @var array rules for validation
     */
    public $rules = [
        'title' => 'required',
        // 'slug' => 'required|unique_site'
    ];

It would probably solve my issue and give me some time to update my blueprints, since it seems to be the way to go, but I’m afraid that fiddling with October files will break some other things.

My I ask what was the issue with it being optional?

Thanks!

HI @froberts0n, I use this:

    slug: 
        hidden: true
        validation: 
            - false
1 Like

Thanks @jan-vince,

Your solution works, even though it doesn’t validate against the YAML definition (false is not a valid validation attribute). So does mine, even though it’s a patch to the core (probably worse than your solution, to be fair!).

I’m just looking for the right way of fixing it for 3.7.6 and on since my web site relies a lot on Tailor models.

Hi @froberts0n,

false is not meant as a validation rule - it will disable validation for a specific field.

The result Laravel validation rule will be like this:

$validator = Validator::make($data, [
    'slug' => ''
]);

Which is perfectly OK - as far as I know :slight_smile:

Indeed, in v3.7 the slug field is now required and must be unique across the site definition. This was always part of the design/plan for blueprints.

We’ve added something to address this in patch v3.7.7. This will remove the validation if the field is hidden and also allow setting validation: false explicitly instead of as an array.

The documentation has also been updated with the content below

I hope this helps!


Disabling Required Fields

The entry record will require the title and slug fields to be populated before they can be saved, additionally, the slug field must also be unique. You may modify this functionality by overriding these fields in your blueprint. Either by setting the validation property to false or setting the hidden property to true and hiding it from the user interface. The following example will disable the validation for both fields and hide the slug field.

fields:
    title:
        validation: false

    slug:
        hidden: true