This shard was officially migrated in to Avram directly - Read PR
AvramSlugify generates slugs for database columns. These slugs can be used for creating nice looking URLs and permalinks.
-
Add the dependency to your
shard.yml:dependencies: avram_slugify: github: luckyframework/avram_slugify version: ~> 0.1
-
Run
shards install -
Require the shard after requiring Avram
If using Lucky, require the shard in your src/shards.cr file after requiring Avram:
# In src/shards.cr
# Put this after `require "avram"`
require "avram_slugify"If not using Lucky, require the shard after Avram:
# In whichever file you require your shards
# Put this after `require "avram"`
require "avram_slugify"Let's say you have an Article model with 2 String columns, slug and
title. You can use AvramSlugify.set to set the slug column to a slugified
version of the title.
class SaveArticle < Article::SaveOperation
before_save do
AvramSlugify.set slug,
using: title,
query: ArticleQuery.new
end
end- The first argument is the attribute you want to store the generated slug
on. In this case
slug, but it could be any String attribute. - The second argument is called a slug candidate. In this case
titleis the slug candidate. - The third argument is the query to use when checking for slug uniqueness.
So if the value of the slug candidate title is "Avram is a great ORM", the
slug value will be set to avram-is-a-great-orm.
You can find record with Avram's built-in query methods.
ArticleQuery.new.slug("avram-is-a-great-orm").firstOr if you want to add a shortcut you can do something like this:
class ArticleQuery < Article::BaseQuery
def find(slug_or_id : String | Int64) : Article
if slug_or_id.is_a?(Int64)
previous_def(slug_or_id)
else
slug(slug_or_id).first
end
end
end
# Find by slug
ArticleQuery.find("avram-is-a-great-orm")
# Find by id
ArticleQuery.find(1_i64)
# Can be scoped like any other query
ArticleQuery.new.account_id(account.id).find("avram-is-a-great-orm")If the slug is not unique, a UUID will be appended to the first slug
candidate (the attribute passed to using).
So if an Article has a slug with hello-world and then you try to save a new
Article with a title set to "Hello World", the slug will not be unique. To
make the slug unique AvramSlugify will append a UUID to the slug.
For example: hello-world-3fa569f5-6678-4f77-a281-fb1b9d850407
To make it less likely that AvramSlugify will have to append a UUID, you can
provide multiple slug candidates in using.
For example, you could do using: [title, author_email]. If the generated
slug from title is already taken, AvramSlugify will try to generate a slug
from author_email. If that doesn't work it will append a UUID to title
Let's say an Article belongs to an Account and you want slugs to be unique per
account. Here's how you'd do that:
class SaveArticle < Article::SaveOperation
# This means you will need to pass in an account when saving/updating
# https://luckyframework.org/guides/database/validating-saving#passing-extra-data-to-operations
needs account : Account
before_save do
AvramSlugify.set slug.
using: title,
# Use the Account to query against Articles in the same Account
query: ArticleQuery.new.account_id(@account.id)
end
endLet's say you have a User with a invite_code that you'd like to be generated
from the first_name and last_name.
You can give an array of attributes and they will be combined when generating the slug:
AvramSlugify.set invite_code,
using: [[first_name, last_name]],
query: UserQuery.newSo if first_name is "Jane" and last_name is "Adler", the generated
slug for invite_code will be "jane-adler".
You must put the array in another array. If you did just
[first_name, last_name]AvramSlugify would usefirst_nameby default andlast_nameif thefirst_nameis not unique
You can also use multiple slug candidates for fallbacks by adding more slug
candidates to the array passed to using:
[
nickname,
[first_name, last_name],
[first_name, last_name, location]
]
Occassionally you may want to use a string as a slug candidate:
using: ["first-#{first_name.value}"]Avram::Attributes can be nil or empty strings so if the slug candidate's
value is nil or an empty string the slug value will be unchanged.
AvramSlugify will not overwrite an existing slug.
If you want to reset a slug, first set the slug value to nil, then run
AvramSlugify.set:
slug.value = nil
AvramSlugify.set slug,
using: title,
query: ArticleQuery.new- Fork it (https://github.com/luckyframework/avram_slugify/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
- Paul Smith - creator and maintainer