Gathering detailed insights and metrics for mongoose-slug-plugin
Gathering detailed insights and metrics for mongoose-slug-plugin
Gathering detailed insights and metrics for mongoose-slug-plugin
Gathering detailed insights and metrics for mongoose-slug-plugin
npm install mongoose-slug-plugin
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
22 Stars
41 Commits
9 Forks
7 Watching
2 Branches
6 Contributors
Updated on 01 Nov 2022
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
17%
124
Compared to previous day
Last week
36.8%
520
Compared to previous week
Last month
66.8%
2,229
Compared to previous month
Last year
-2.6%
15,937
Compared to previous year
Slugs for Mongoose with history and i18n support (uses speakingurl by default, but you can use any slug library such as limax, slugify, mollusc, or slugme)
npm:
1npm install mongoose-slug-plugin
yarn:
1yarn add mongoose-slug-plugin
Add the plugin to your project (it will automatically generate a slug when the document is validated based off the template string passed)
1const mongooseSlugPlugin = require('mongoose-slug-plugin'); 2const mongoose = require('mongoose'); 3 4const BlogPost = new mongoose.Schema({ 5 title: String 6}); 7 8BlogPost.plugin(mongooseSlugPlugin, { tmpl: '<%=title%>' }); 9 10module.exports = mongoose.model('BlogPost', BlogPost);
If you need to render some custom function in the template string for display purposes, such as outputting a formatted date with dayjs:
1const dayjs = require('dayjs'); 2 3const mongooseSlugPlugin = require('mongoose-slug-plugin'); 4const mongoose = require('mongoose'); 5 6const BlogPost = new mongoose.Schema({ 7 title: { type: String, required: true, unique: true }, 8 posted_at: { type: Date, required: true } 9}); 10 11BlogPost.plugin(mongooseSlugPlugin, { 12 tmpl: "<%=title%>-<%=dayjs(posted_at).format('YYYY-MM-DD')%>", 13 locals: { dayjs } 14}); 15 16module.exports = mongoose.model('BlogPost', BlogPost);
If you're using Koa, here's an example showing how to lookup a slug or an archived slug and properly 301 redirect:
1const Koa = require('koa'); 2const Router = require('koa-router'); 3const Boom = require('boom'); 4 5const BlogPosts = require('./blog-post'); 6 7const app = new Koa(); 8const router = new Router(); 9 10router.get('/blog/:slug', async (ctx, next) => { 11 try { 12 // lookup the blog post by the slug parameter 13 const blogPost = await BlogPosts.findOne({ slug: ctx.params.slug }); 14 15 // if we found it then return early and render the blog post 16 if (blogPost) return ctx.render('blog-post', { title: blogPost.title, blogPost }); 17 18 // check if the slug changed for the post we're trying to lookup 19 blogPost = await BlogPosts.findOne({ slug_history: ctx.params.slug }); 20 21 // 301 permanent redirect to new blog post slug if it was found 22 if (blogPost) return ctx.redirect(301, `/blog/${blogPost.slug}`); 23 24 // if no blog post found then throw a nice 404 error 25 // this assumes that you're using `koa-better-error-handler` 26 // and also using `koa-404-handler`, but you don't necessarily need to 27 // since koa automatically sets 404 status code if nothing found 28 // <https://github.com/ladjs/koa-better-error-handler> 29 // <https://github.com/ladjs/koa-404-handler> 30 return next(); 31 32 } catch (err) { 33 ctx.throw(err); 34 } 35}); 36 37app.use(router.routes()); 38app.listen(3000);
If you're using Express, here's an example showing how to lookup a slug or an archived slug and properly 301 redirect:
1TODO
Note that you also have access to a static function on the model called
getUniqueSlug
.
This function accepts an _id
and str
argument. The _id
being the ObjectID of the document and str
being the slug you're searching for to ensure uniqueness.
This function is used internally by the plugin to recursively ensure uniqueness.
If you have to write a script to automatically set slugs across a collection, you can use the getUniqueSlug
static method this package exposes on models.
For example, if you want to programmatically set all blog posts to have slugs, run this script (note that you should run the updates serially as the example shows to prevent slug conflicts):
1const Promise = require('bluebird'); // exposes `Promise.each` 2 3const BlogPost = require('../app/models/blog-post.js'); 4 5(async () => { 6 const blogPosts = await BlogPost.find({}).exec(); 7 await Promise.each(blogPosts, async blogPost => { 8 blogPost.slug = null; 9 blogPost.slug = await BlogPost.getUniqueSlug(blogPost._id, blogPost.title); 10 return blogPost.save(); 11 })); 12})();
Here are the default options passed to the plugin:
tmpl
(String) - Required, this should be a lodash template string (e.g. <%=title%>
to use the blog post title as the slug)locals
(Object) - Defaults to an empty object, but you can pass a custom object that will be inherited for use in the lodash template string (see above example for how you could use dayjs to render a document's date formatted in the slug)alwaysUpdateSlug
(Boolean) - Defaults to true
(basically this will re-set the slug to the value it should be based off the template string every time the document is validated (or saved for instance due to pre-save hook in turn calling pre-validate in Mongoose)errorMessage
(String) - Defaults to Slug was missing or blank
, this is a String that is returned for failed validation (note that it gets translated based off the this.locale
field if it is set on the document (see Lad for more insight into how this works))logger
(Object) - defaults to console
, but you might want to use Lad's loggerslugField
(String) - defaults to slug
, this is the field used for storing the slug for the documenthistoryField
(String) - defaults to slug_history
, this is the field used for storing a document's slug historyi18n
(Object|Boolean) - defaults to false
, but accepts a i18n
object from Lad's i18nslug
(Function) - Defaults to speakingurl
, but it is a function that converts a string into a slug (see below Custom Slug Libary examples)slugOptions
(Object) - An object of options to pass to the slug function when invoked as specified in options.slug
If you're using the default slug library speakingurl
, then you might want to pass the option slugOptions: { "'": '' }
in order to fix contractions.
For example, if your title is "Jason's Blog Post", you probably want the slug to be "jasons-blog-post" as opposed to "jason-s-blog-post". This option will fix that.
See pid/speakingurl#105 for more information.
If a slug of "foo-bar" already exists, and if we are inserting a new document that also has a slug of "foo-bar", then this new slug will automatically become "foo-bar-1".
If you don't want to use the library speakingurl
for generating slugs (which this package uses by default), then you can pass a custom slug
function:
limax example:
1const limax = require('limax'); 2 3BlogPost.plugin(mongooseSlugPlugin, { tmpl: '<%=title%>', slug: limax });
slugify example:
1const slugify = require('slugify'); 2 3BlogPost.plugin(mongooseSlugPlugin, { tmpl: '<%=title%>', slug: slugify });
mollusc example:
1const slug = require('mollusc'); 2 3BlogPost.plugin(mongooseSlugPlugin, { tmpl: '<%=title%>', slug });
slugme example:
1const slugme = require('slugme'); 2 3BlogPost.plugin(mongooseSlugPlugin, { tmpl: '<%=title%>', slug: slugme });
I created this package despite knowing that other alternatives like it exist for these reasons:
speakingurl
packageName | Website |
---|---|
Nick Baugh | http://niftylettuce.com/ |
shadowgate15 | https://github.com/shadowgate15 |
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
security policy file detected
Details
Reason
Found 3/27 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
40 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More