Git Product home page Git Product logo

nova-sluggable's Introduction

Slug field for Laravel Nova

Latest Version on Packagist

Slug field for Laravel Nova that can generate unique slug for your model while typing.

nova-sluggable demo

Installation

You can install the package in to a Laravel app that uses Nova via composer:

composer require drobee/nova-sluggable

Usage

Add a new SluggableText and a Slug field to your Nova Resource:

use Drobee\NovaSluggable\SluggableText;
use Drobee\NovaSluggable\Slug;

class User extends Resource
{
    // ...

    public function fields(Request $request)
    {
        return [
            // ...

            SluggableText::make('Title'),
            Slug::make('Slug'),

            // ...
        ];
    }
}

When the user types a string in the SluggableText field the value is being sent the API to generate the slug and and then it sets the Slug field's value to the that. The slug is updated on every key up event, but it can be tied to blur event on the title field.

By default it looks for a Slug type field with the name Slug.

In order to work properly every defined SluggableText field need a corresponding Slug field.

Options

Slug field with custom name

Set the Slug fields name on the SluggableText field with the slug() method:

SluggableText::make('Title')->slug('SEO Title');
Slug::make('SEO Title', 'slug');

Language

Set the language to use for the generation with the Slug field's slugLanguage() method:

Slug::make('Slug')->slugLanguage('hu');

Default value: en

Maximum length

Limit the maximum length of the generated slug with the Slug field's slugMaxLength() method:

Slug::make('Slug')->slugMaxLength(100);

Default value: 255

Maximum length

Set the string all the whitespaces will be replaced with with the Slug field's slugSeparator() method:

Slug::make('Slug')->slugSeparator('.');

Default value: -

Note: the generated slug may be few characters longer than the value specified, due to the suffix which is added to make it unique.

Update event

By default the slug updates on every keyup event, but you can tie it to the blur event:

Slug::make('Slug')->event('blur');

Accepted values: keyup, blur

Default value: keyup

Unique slug and Eloquent model

The generated slugs won't be unique unless you call the slugUnique() method on your Slug field.

You also need to specify what Eloquent model should the generator use to make the slug unique by calling the slugModel() method. In most cases you would want to use the same Eloquent model as your resource. To do so call the method with the resource's static $model attribute.

Slug::make('Slug')
    ->slugUnique()
    ->slugModel(static::$model);

When these to options are set the generated slug will be unique on the set model regarding the attribute value of the Slug field.

Usage with Spatie\Sluggable

If the Eloquent model you specified with slugModel() uses Spatie\Sluggable's HasSlug trait and implements its getSlugOptions() method, then you don't have to set the separator, maximum length or language for the field. In such cases the generator uses the values you already set on your model.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Acknowledgments

Special thanks to:

nova-sluggable's People

Contributors

alexhiggins avatar bashgeek avatar cookieseater avatar crynobone avatar drobee avatar guillaumesozen avatar kduma avatar kukac7 avatar marcreichel avatar mdavis1982 avatar u12206050 avatar wize-wiz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nova-sluggable's Issues

doNotGenerateSlugsOnUpdate()

Hi,

I hope that my slug will not be updated when I updated my name
Is that possible?

I have tried to include the code below, but it doesnt work
public function getSlugOptions() : SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('name')
->saveSlugsTo('slug')
->doNotGenerateSlugsOnUpdate();
}

hidden input option

Is it possible to submit the field as a hidden input?

For example adding ->hidden() to the chain like:

            SluggableText::make('Name')
                ->rules('required'),
            Slug::make('Slug')
                ->slugUnique()
                ->slugModel(static::$model)
                ->rules('required', 'alpha_dash', 'max:80')
                ->creationRules('unique:somegroup,slug')
                ->hidden(),

I know I can do this through a custom field or by just setting the value in the model on ::saving but it would be nice to still make use of this packages rules, validation etc.

I'd like to set the value but just remove the visibility for some users.

Upgrade to support Laravel 8

Hello,

Can you please update this package to be Laravel 8 compatible?

I think the problem is that it needs to use the latest version of illuminate/support.

Thanks


Here is my composer update ouput:

Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: don't install laravel/framework 5.7.x-dev
    - Conclusion: remove drobee/nova-sluggable 1.2.3|install laravel/framework 5.7.x-dev
    - Conclusion: don't install drobee/nova-sluggable 1.2.3
    - Conclusion: don't install drobee/nova-sluggable 1.2.2
    - Conclusion: don't install drobee/nova-sluggable 1.2.1
    - Conclusion: don't install laravel/framework v8.4.0
    - Conclusion: don't install laravel/framework v8.3.0
    - Conclusion: don't install laravel/framework v8.2.0
    - Conclusion: don't install laravel/framework v8.1.0
    - Conclusion: don't install laravel/framework v8.0.4
    - Conclusion: don't install laravel/framework v8.0.3
    - Conclusion: don't install laravel/framework v8.0.2
    - Conclusion: don't install laravel/framework v8.0.1
    - Installation request for drobee/nova-sluggable ^1.2 -> satisfiable by drobee/nova-sluggable[1.2.0, 1.2.1, 1.2.2, 1.2.3].
    - Conclusion: don't install laravel/framework v8.0.0
    - drobee/nova-sluggable 1.2.0 requires illuminate/support 5.6.*|5.7.*|5.8.*|6.0.* -> satisfiable by laravel/framework[5.6.x-dev, 5.7.x-dev, 5.8.x-dev], illuminate/support[5.6.x-dev, 5.7.17, 5.7.18, 5.7.19, 5.7.x-dev, 5.8.x-dev, v5.6.0, v5.6.1, v5.6.10, v5.6.11, v5.6.12, v5.6.13, v5.6.14, v5.6.15, v5.6.16, v5.6.17, v5.6.19, v5.6.2, v5.6.20, v5.6.21, v5.6.22, v5.6.23, v5.6.24, v5.6.25, v5.6.26, v5.6.27, v5.6.28, v5.6.29, v5.6.3, v5.6.30, v5.6.31, v5.6.32, v5.6.33, v5.6.34, v5.6.35, v5.6.36, v5.6.37, v5.6.38, v5.6.39, v5.6.4, v5.6.5, v5.6.6, v5.6.7, v5.6.8, v5.6.9, v5.7.0, v5.7.1, v5.7.10, v5.7.11, v5.7.15, v5.7.2, v5.7.20, v5.7.21, v5.7.22, v5.7.23, v5.7.26, v5.7.27, v5.7.28, v5.7.3, v5.7.4, v5.7.5, v5.7.6, v5.7.7, v5.7.8, v5.7.9, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.36, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4].
    - Can only install one of: laravel/framework[8.x-dev, 5.6.x-dev].
    - Can only install one of: laravel/framework[8.x-dev, 5.8.x-dev].
    - don't install illuminate/support v6.0.0|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v6.0.1|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v6.0.2|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v6.0.3|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v6.0.4|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.7.17|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.7.18|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.7.19|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.7.x-dev|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.0|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.1|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.10|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.11|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.15|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.2|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.20|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.21|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.22|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.23|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.26|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.27|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.28|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.3|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.4|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.5|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.6|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.7|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.8|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.7.9|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.8.x-dev|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.0|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.11|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.12|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.14|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.15|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.17|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.18|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.19|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.2|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.20|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.22|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.24|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.27|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.28|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.29|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.3|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.30|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.31|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.32|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.33|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.34|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.35|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.36|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.4|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.8|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.8.9|don't install laravel/framework 8.x-dev
    - don't install illuminate/support 5.6.x-dev|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.0|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.1|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.10|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.11|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.12|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.13|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.14|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.15|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.16|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.17|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.19|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.2|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.20|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.21|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.22|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.23|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.24|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.25|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.26|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.27|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.28|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.29|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.3|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.30|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.31|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.32|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.33|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.34|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.35|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.36|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.37|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.38|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.39|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.4|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.5|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.6|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.7|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.8|don't install laravel/framework 8.x-dev
    - don't install illuminate/support v5.6.9|don't install laravel/framework 8.x-dev
    - Installation request for laravel/framework ^8.0 -> satisfiable by laravel/framework[8.x-dev, v8.0.0, v8.0.1, v8.0.2, v8.0.3, v8.0.4, v8.1.0, v8.2.0, v8.3.0, v8.4.0].

Translation with "optimistdigital/nova-translatable"

Hey there,
thank you for your great Package!

Recently i needed to get it working with the Package: "optimistdigital/nova-translatable" and found a pretty easy way to get it working.

In "resources/js/components/SluggableText/FormField.vue" in Line 27 (handleChange()) i edited the Function like this:

handleChange(event) {            
    let lang = this.field.attribute.split('.').length() > 1
        ? this.field.attribute.split('.').pop()
        : null
    let name = this.slugField

    if(lang) {
        name += '-' + lang
    }

    Nova.$emit('field-update-' + event.type + '-' + name, {
        value: event.target.value
    })
},

In "resources/js/components/Slug/FormField.vue" in Line 39 (mounted()) i edited the Function like this:

mounted() {
    const eventType = this.field.options.event || 'keyup';
    let lang = this.field.attribute.split('.').length() > 1
        ? this.field.attribute.split('.').pop()
        : null
    let name = this.field.name
    
    if(lang) {
        name += '-' + lang
    }

    Nova.$on('field-update-' + eventType + '-' + name, ({value}) => {
        this.generateSlug(value)
    })
},

This also works without translatable. Maybe you can integrate this to the existing Package.

Best
Julian

Generate Button

Hi there,

Would it be possible to add an option where the slug is generated by clicking a button instead of keyup and blur? I'd only like to generate the slug if it's required. As is, the slug will change when the title field is updated. I don't really want the slug automatically change if I'm editing vs. creating.

Thanks!

Compatibility with Laravel 9

composer require drobee/nova-sluggable
Using version ^1.2 for drobee/nova-sluggable
./composer.json has been updated
Running composer update drobee/nova-sluggable
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

Problem 1
- drobee/nova-sluggable[1.2.0, ..., 1.2.1] require illuminate/support 5.6.|5.7.|5.8.|6.0. -> found illuminate/support[v5.6.0, ..., 5.8.x-dev, v6.0.0, ..., v6.0.4] but these were not loaded, likely because it conflicts with another require.
- drobee/nova-sluggable 1.2.2 requires illuminate/support 5.6.|5.7.|5.8.|6. -> found illuminate/support[v5.6.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev] but these were not loaded, likely because it conflicts with another require.
- drobee/nova-sluggable 1.2.3 requires illuminate/support 5.6.|5.7.|5.8.|6.|7.* -> found illuminate/support[v5.6.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev] but these were not loaded, likely because it conflicts with another require.
- drobee/nova-sluggable[1.2.4, ..., 1.2.6] require illuminate/support 5.6.|5.7.|5.8.|6.|7.|8. -> found illuminate/support[v5.6.0, ..., 5.8.x-dev, v6.0.0, ..., 6.x-dev, v7.0.0, ..., 7.x-dev, v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
- Root composer.json requires drobee/nova-sluggable ^1.2 -> satisfiable by drobee/nova-sluggable[1.2.0, ..., 1.2.6].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require drobee/nova-sluggable:*" to figure out if any version is installable, or "composer require drobee/nova-sluggable:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

Slug was generated too slow

Thank you for your Field, it works very well except the slug was generated really slow. When I finished typing, it takes 3-5 seconds to complete the slug field.

Does it cause by making too many requests for every button I typed?

Thank you!

slug not coming in arabic language

I am adding the title in the Arabic letter but the auto slug is creating in English letters.

I couldn't find the languages which are supported- is Arabic is supported?

I am using the following code:- Slug::make('Slug')->slugLanguage('ar')

Thanks in advance!

Add method to disable event

Like in #9, I too was searching for a solution to disable the event when editing a resource.

E.g. I have a news resource where the title generates a slug, but on edit this slug should not be changed. Now I could simply do an if/else if the request is an update or not, and just replace the Slug field with a disabled text field, but easier would be if I could just add a method like disableEvents($disable = true) with a default set to true.

I don't know what you (@drobee) think about this idea, but I did a quick edit and came with this solution.

src/Slug.php

// constructor
public function __construct(...) {
  ...   
  $this->disableEvents(false); // default to false
  ...
}

// method
public function disableEvents(bool $disable = true) {
  // I choose `meta` because somehow setOptions() sets a boolean to string "1" instead of `true`.
  return $this->withMeta(['disableEvents' => $disable]);
}

resources/js/components/Slug/FormField.vue

Changed the mounted method for a return if event should not be used.

    mounted() {
        // return if event should be disabled
        if(this.field.disableEvents) {
            return;
        }
        const eventType = this.field.options.event || 'keyup';
        Nova.$on('field-update-' + eventType + '-' + this.field.name, ({value}) => {
          this.generateSlug(value);
    },

I could make PR if you agree.


Another thing, I also added a delay for the generate slug request.

src/Slug.php

// added eventDelay to default options
protected $options = [
    'event' => 'keyup',
    'eventDelay' => 200
];

// method
public function eventDelay(int $delay) {
  return $this->setOption('eventDelay', $delay);
}

Mounted function with delay

// return if event disabled
if(this.field.disableEvents) {
    return;
}
this.eventDelayTimeout = null;
const eventType = this.field.options.event || 'keyup';
Nova.$on('field-update-' + eventType + '-' + this.field.name, ({value}) => {
    // clear timeout if any
    if(this.eventDelayTimeout !== null) { clearTimeout(this.eventDelayTimeout); }
    // delay generation of slug
    this.eventDelayTimeout = setTimeout((function() {
        this.generateSlug(value)
    }).bind(this), this.options.eventDelay);
})

Help Text Doesn't Display

When using this field in Laravel Nova 3.14.0, I'm not seeing the help text displayed underneath either of the two text inputs.

I've tried it in a fresh install and the behaviour is the same.

SluggableText::make('Title')
    ->rules('required', 'string', 'min:3', 'max:255')
    ->help("The blog post's title"),

image

Slug Update Event Incredibly Slow

I am not 100% sure what is going on under the hood, but I just did a fresh install on a new project, and the Slug field takes a ridiculous amount of time to update.

I do not think it is something in my local environment, when I switch to: benjaminhirsch/nova-slug-field this problem disappears and updates happen near-instant.

Laravel 6.0 support

I tested it manually, it "just works" if adding the 6.0 version to composer.json.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.