Giter Club home page Giter Club logo

adonis-lucid-slugify's Introduction

Adonis Lucid Slugify

Works with @adonisjs/lucid 5.0.3 or greater.

This addon adds the functionality to generate unique slugs for multiple fields when saving them to the database using Lucid models.

NPM Version Build Status Coveralls

Installation

Make sure to install it using adonis install over npm or yarn.

adonis install @adonisjs/lucid-slugify

# yarn
adonis install @adonisjs/lucid-slugify --yarn

Next, make sure to read the instructions.md file.

Features ⭐️

  1. Url friendly strings.
  2. Handles unicode
  3. Works seamlessly with updates
  4. Uniqueness guaranteed.

Using trait ✍️

const Model = use('Model')

class Post extends Model {
  static boot () {
    super.boot()

    this.addTrait('@provider:Lucid/Slugify', {
      fields: { slug: 'title' },
      strategy: 'dbIncrement',
      disableUpdates: false
    })
  }
}

Options

{
"fields":

key/value pair of fields, you want to generate slugs for..

The key is the slug field and value is the field whose value will be used for generating the slug

"strategy":

It can be raw function or one of the predefined strategies.

"disableUpdates":

Depending upon your app, you may never want slugs to change. So disable the update hook.

}

In action 🤾🏻‍♂️

Let's use the post model and generate a new slug.

const post = new Post()
post.title = 'Adonis 101'
await post.save()

console.log(post.slug) // adonis-101

On update it will re-generate the slug, only if the value of the actual field has been changed.

const post = await Post().find(1)
await post.save() // noop

post.title = 'A new title'
await post.save() // slug re-generated

console.log(post.slug) // a-new-title

Strategies 👩🏻‍🔬

Generating unique slugs is a hard problem, since each application has unique requirements and constraints. So instead of defining a single strategy to generate slugs, the add-on keeps it flexible to define custom strategies.

2 different strategies are shipped by default and here's how they work.


dbIncrement

The dbIncrement strategy adds a counter to the slugs, when duplicate slugs are found.

Works great with mysql and pg, whereas sqlite has some edge cases.

Let's assume a post with slug -> hello_world already exists.

+----+-------------+-------------+
| id | title       | slug        |
+----+-------------+-------------+
| 1  | Hello world | hello-world |
+----+-------------+-------------+

Now if we will add a new slug, it will add -1, -2 respectively to it.

+----+-------------+---------------+
| id | title       | slug          |
+----+-------------+---------------+
| 1  | Hello world | hello-world   |
| 2  | Hello world | hello-world-1 |
| 3  | Hello world | hello-world-2 |
+----+-------------+---------------+

As mentioned above, this strategy fails in some edge cases when using sqlite. Let's take the following database table structure.

+----+-------------------+-------------------+
| id | title             | slug              |
+----+-------------------+-------------------+
| 1  | Hello world       | hello-world       |
| 2  | Hello world       | hello-world-1     |
| 3  | Hello world       | hello-world-2     |
| 4  | Hello world fanny | hello-world-fanny |
+----+-------------------+-------------------+

In sqlite adding a new post with Hello world title will fail and here's why.

  1. The strategy will find latest row from the database matching slug LIKE hello-world%.
  2. The return row will be hello-world-fanny and not hello-world-2 and hence the counter logic will fail.
  3. In MySQL and PostgreSQL, we make use of Regular expressions REGEXP ^hello-world(-[0-9*])?$ and pull the correct row.

shortId

This strategy works great regardless of the database engine in use, the only downside is, the URL's are not as pretty as dbIncrement strategy.

Make sure to install shortid as dependency before using it

+----+-------------+----------------------+
| id | title       | slug                 |
+----+-------------+----------------------+
| 1  | Hello world | hello-world-23TplPdS |
+----+-------------+----------------------+

The random number after the actual slug is generated using shortid and it ensures uniqueness.

Defining custom strategies 👨🏻‍💻

You can define your strategies just by defining a function, and here's what a strategy is responsible for.

  1. It receives the base slug generated by the core library.
  2. It should return back a string ensuring the return value is unique.
this.addTrait('@provider:Lucid/Slugify', {
  fields: { slug: 'title' },
  strategy: async (field, value, modelInstance) => {
    return `${modelInstance.author_id}-${value}`
  }
})

The above is a simple implementation where we prepend the author_id to slug and ofcourse, we assumed that author_id will be set on the model instance.

const post = new Post()
post.author_id = auth.user.id

post.title = 'Spacex Launch'
await post.save()

console.log(post.slug) // 1-spacex-launch

How about more strategies?

You just need to find the one that fits your needs. Wordpress has been generating slugs for years and here's a screenshot of options they give.

Tests

The code is tested with mysql, pg and sqlite only. Tests are written using japa.

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.