{"id":13486388,"url":"https://github.com/luckyframework/avram_slugify","last_synced_at":"2025-03-27T20:33:03.825Z","repository":{"id":45855039,"uuid":"251095911","full_name":"luckyframework/avram_slugify","owner":"luckyframework","description":"AvramSlugify generates slugs for database columns. These slugs can be used for creating nice looking URLs, permalinks, invite codes, etc.","archived":true,"fork":false,"pushed_at":"2022-04-07T23:44:42.000Z","size":32,"stargazers_count":13,"open_issues_count":1,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-08-01T18:26:27.769Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luckyframework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-29T17:49:53.000Z","updated_at":"2023-01-28T00:22:40.000Z","dependencies_parsed_at":"2022-09-13T02:40:22.795Z","dependency_job_id":null,"html_url":"https://github.com/luckyframework/avram_slugify","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckyframework%2Favram_slugify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckyframework%2Favram_slugify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckyframework%2Favram_slugify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckyframework%2Favram_slugify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luckyframework","download_url":"https://codeload.github.com/luckyframework/avram_slugify/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222313940,"owners_count":16965412,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T18:00:45.006Z","updated_at":"2024-10-30T21:31:33.241Z","avatar_url":"https://github.com/luckyframework.png","language":"Crystal","funding_links":[],"categories":[":gem: Lucky Shards"],"sub_categories":[],"readme":"# AvramSlugify (DEPRECATED)\n\n*This shard was officially migrated in to Avram directly* - [Read PR](https://github.com/luckyframework/avram/pull/786)\n\nAvramSlugify generates slugs for database columns. These slugs can be used for\ncreating nice looking URLs and permalinks.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n   ```yaml\n   dependencies:\n     avram_slugify:\n       github: luckyframework/avram_slugify\n       version: ~\u003e 0.1\n   ```\n\n1. Run `shards install`\n\n1. Require the shard after requiring Avram\n\n**If using Lucky,** require the shard in your `src/shards.cr` file after requiring Avram:\n\n```crystal\n# In src/shards.cr\n# Put this after `require \"avram\"`\nrequire \"avram_slugify\"\n```\n**If not using Lucky,** require the shard after Avram:\n\n```crystal\n# In whichever file you require your shards\n# Put this after `require \"avram\"`\nrequire \"avram_slugify\"\n```\n\n## Usage\n\nLet's say you have an `Article` model with 2 `String` columns, `slug` and\n`title`. You can use `AvramSlugify.set` to set the `slug` column to a slugified\nversion of the `title`.\n\n```crystal\nclass SaveArticle \u003c Article::SaveOperation\n  before_save do\n    AvramSlugify.set slug,\n      using: title,\n      query: ArticleQuery.new\n  end\nend\n```\n\n1. The first argument is the attribute you want to store the generated slug\n   on. In this case `slug`, but it could be any String attribute.\n1. The second argument is called a **slug candidate**. In this case `title`\n   is the slug candidate.\n1. The third argument is the query to use when checking for slug uniqueness.\n\nSo if the value of the slug candidate `title` is `\"Avram is a great ORM\"`, the\n`slug` value will be set to `avram-is-a-great-orm`.\n\n### Finding records\n\nYou can find record with Avram's built-in query methods.\n\n```crystal\nArticleQuery.new.slug(\"avram-is-a-great-orm\").first\n```\n\nOr if you want to add a shortcut you can do something like this:\n\n```crystal\nclass ArticleQuery \u003c Article::BaseQuery\n   def find(slug_or_id : String | Int64) : Article\n     if slug_or_id.is_a?(Int64)\n       previous_def(slug_or_id)\n    else\n       slug(slug_or_id).first\n    end\n   end\nend\n\n# Find by slug\nArticleQuery.find(\"avram-is-a-great-orm\") \n# Find by id\nArticleQuery.find(1_i64) \n# Can be scoped like any other query\nArticleQuery.new.account_id(account.id).find(\"avram-is-a-great-orm\")\n```\n\n### What if the generated slug is not unique?\n\nIf the slug is not unique, a `UUID` will be appended to the first slug\ncandidate (the attribute passed to `using`).\n\nSo if an `Article` has a slug with `hello-world` and then you try to save a *new*\nArticle with a `title` set to `\"Hello World\"`, the slug will not be unique. To\nmake the slug unique `AvramSlugify` will append a `UUID` to the slug.\nFor example: `hello-world-3fa569f5-6678-4f77-a281-fb1b9d850407`\n\n### Using multiple slug candidates\n\nTo make it less likely that `AvramSlugify` will have to append a `UUID`, you can\nprovide multiple slug candidates in `using`.\n\nFor example, you could do `using: [title, author_email]`. If the generated\nslug from `title` is already taken, AvramSlugify will try to generate a slug\nfrom `author_email`. If that doesn't work it will append a UUID to `title`\n\n### Scoping uniqueness check\n\nLet's say an `Article` belongs to an `Account` and you want slugs to be unique per\naccount. Here's how you'd do that:\n\n```crystal\nclass SaveArticle \u003c Article::SaveOperation\n  # This means you will need to pass in an account when saving/updating\n  # https://luckyframework.org/guides/database/validating-saving#passing-extra-data-to-operations\n  needs account : Account\n\n  before_save do\n    AvramSlugify.set slug.\n      using: title,\n      # Use the Account to query against Articles in the same Account\n      query: ArticleQuery.new.account_id(@account.id)\n  end\nend\n```\n\n### Combining multiple attributes for a slug\n\nLet's say you have a `User` with a `invite_code` that you'd like to be generated\nfrom the `first_name` and `last_name`.\n\nYou can give an array of attributes and they will be combined when generating\nthe slug:\n\n```crystal\nAvramSlugify.set invite_code,\n  using: [[first_name, last_name]],\n  query: UserQuery.new\n```\n\nSo if `first_name` is `\"Jane\"` and `last_name` is `\"Adler\"`, the generated\nslug for `invite_code` will be `\"jane-adler\"`.\n\n\u003e You must put the array in another array. If you did just\n\u003e `[first_name, last_name]` AvramSlugify would use `first_name` by default and\n\u003e `last_name` if the `first_name` is not unique\n\nYou can also use multiple slug candidates for fallbacks by adding more slug\ncandidates to the array passed to `using`:\n\n```\n[\n  nickname,\n  [first_name, last_name],\n  [first_name, last_name, location]\n]\n```\n\n### Using strings as slug candidates\n\nOccassionally you may want to use a string as a slug candidate:\n\n```crystal\nusing: [\"first-#{first_name.value}\"]\n```\n\n### What if the slug candidate is blank?\n\n`Avram::Attribute`s can be nil or empty strings so if the slug candidate's\nvalue is nil or an empty string the slug value will be unchanged.\n\n### What if the slug is already set?\n\n`AvramSlugify` will not overwrite an existing slug.\n\nIf you want to reset a slug, first set the slug value to `nil`, then run\n`AvramSlugify.set`:\n\n```crystal\nslug.value = nil\nAvramSlugify.set slug,\n  using: title,\n  query: ArticleQuery.new\n```\n\n## Contributing\n\n1. Fork it (\u003chttps://github.com/luckyframework/avram_slugify/fork\u003e)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Paul Smith](https://github.com/paulcsmith) - creator and maintainer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluckyframework%2Favram_slugify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluckyframework%2Favram_slugify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluckyframework%2Favram_slugify/lists"}