Generate URL slugs based on document fields in Meteor 1.0

Wednesday, December 10, 2014

In this post I will show you, how to generate friendly URLs based on document fields in Meteor 1.0. If you are following the tutorial in the great book Discover Meteor and reached chapter 5.3, you should have a Meteor webapp including a collection of post documents in the Mongo database. You should have written a route to a specific post, which is located in lib/router.js:

1
2
3
4
Router.route('/posts/:_id', {
  name: 'postPage',
  data: function() { return Posts.findOne(this.params._id); }
});

With this route it is possible to browse directly to a post by using the URL /posts/<MyPostID>. The Problem using this approach is that the URLs are not really human readable, since the IDs of a collection Item look like CWi6eMWrKncyJtYwX. It would be much better if the URL would be based on the title of the post, for example: /posts/my-fancy-post. To achieve that, you should add a new field in the post documents called slug. An example post document could look like this:

1
2
3
4
5
{
  title: 'My fancy post',
  url: 'http://blog.pedesen.de/',
  slug: 'my-fancy-post'
}

To tell Meteor to use the slug instead of the id for the routing, you have to edit the route like this:

1
2
3
4
Router.route('/posts/:slug', {
  name: 'postPage',
  data: function() { return Posts.findOne({'slug': this.params.slug}); }
});

Thats it! If you browse to /posts/my-fancy-post, you get the corresponding post. If you have followed the book through chapter 7.6, you already added the functionality to add new posts using a form. In this case you would have to manually add a slug string every time a new post is created. It would be much better, if the slug field would be generated automatically based on the title field. This means converting its chars to lower case and substituting spaces with hyphens and some other escaping. For this case you could define a function yourself or use the ‘slugify’ function from the Underscore.string extension. To add this string extension to the Underscore library used in Meteor, you could use the meteor-underscore-string library, which can be added to your Meteor project like this:

meteor add wizonesolutions:underscore-string

If the underscore-string library was successfully added to the project, we can use the function _.slugify(string) in our code. To automatically create a slug whenever a new post is inserted, you have to add the slug field to the _.extend function. According to the tutorial in the book it is located at lib/collections/posts.js:

1
2
3
4
5
6
7
8
  ...
  var post = _.extend(postAttributes, {
    userId: user._id,
    author: user.username,
    slug: _.slugify(postAttributes.title),
    submitted: new Date()
  });
  ...

Now, every time a new post is created (by only using title and url form fields), the slug field will be generated automatically from the title field and will be stored in the post document.