简体   繁体   中英

Using Slugs in Meteor's Iron Router

I'm trying to define an Iron Router route to use a slug: ie. a string title but with spaces replaced by hyphens.

Instead of /news/breaking%20news , we want it to be /news/breaking-news .

Router.map(function() {
    this.route('news', {
        path: '/news/:title'
    })
})

To achieve this, do we need to create a new document field slug with the slug string and use path: '/news/:slug ? Or is there a more elegant method that avoids this redundant field?

App is using packages aldeed:simple-schema , aldeed:collection2 and dburles:collection-helpers if those help.

The constraining issue is the 1-way, non-reversible transformation from the actual title to the slug (eg, "foo-bar" and "foo bar" both end up with the same slug, "foo-bar", so when you see "foo-bar" you don't know what the actual title is, so you can't look it up). So unless you can control for that (eg, adding the slug to the document as you suggest, or enforcing a strict no-hyphens policy for titles in the application), you'll need a way to store the mapping.

One potential way around this would be to include the document ID in the URL and have a meaningless slug, which can be filled in by the router itself:

Router.route('/news/:_id/:slug?', ...) 

Then only use the _id in the actual routing. Note that this allows you to put whatever you want in the URL after the _id, so that 'news/[_id]/foo-bar' and 'news/_id/foo%20bar' both go to the same page, (news/[_id]), but so does 'news/[_id]/this_is_completely_meaningless.' In the router, you can then redirect to the appropriate URL as needed:

Router.route('/news/:_id/:slug?', {
  name: 'news',
  data: function() { return news.findOne({_id: this.params._id}); },
  onBeforeAction: function() { 
    var data = this.data();
    if (data) {
      var realUrl = '/' + data._id + '/' + slugify(data.title); // the desired URL, incl. whatever your slug fn is
      if (this.url.indexOf(realUrl) < 0) { 
        this.redirect('/news' + realUrl); // if we aren't at the desired URL, take us there
      }
    }

    this.next();
  }
}); 

You'd then have to control for any "share this page" functionality to ensure that it gives the desired URL, but if anyone tries to go to news/[_id]/this_is_completely_meaningless it'll redirect them to news/[_id]/foo-bar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM