在Meteor的铁路由器中使用Slugs

时间:2015-03-18 19:35:03

标签: javascript node.js meteor iron-router

我试图定义铁路由器路由以使用slug:ie。字符串title但空格用连字符替换。

而不是/news/breaking%20news,我们希望它是/news/breaking-news

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

为实现这一目标,我们是否需要使用slug字符串创建一个新文档字段slug并使用path: '/news/:slug?或者是否有更优雅的方法可以避免这个多余的领域?

应用正在使用包aldeed:simple-schemaaldeed:collection2dburles:collection-helpers,如果有帮助的话。

1 个答案:

答案 0 :(得分:4)

约束问题是从实际标题到slug的单向,不可逆转换(例如,“foo-bar”和“foo bar”都以相同的slug结尾,“foo-bar”,所以当你看到“foo-bar”时你不知道实际的标题是什么,所以你无法查找它。因此,除非您可以控制(例如,按照您的建议将slug添加到文档中,或者对应用程序中的标题强制执行严格的无连字策略),否则您需要一种方法来存储映射。

一种可能的方法是在URL中包含文档ID,并且有一个无意义的slug,可以由路由器本身填写:

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

然后仅在实际路由中使用_id。请注意,这允许您在_id后面的URL中放置您想要的任何内容,以便'news / [_ id] / foo-bar'和'news / _id / foo%20bar'都转到同一页面,(新闻/ [_id]),但'news / [_ id] / this_is_completely_meaningless。'也是如此。在路由器中,您可以根据需要重定向到相应的URL:

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();
  }
}); 

然后你必须控制任何“共享此页面”功能,以确保它提供所需的URL,但如果有人试图转到新闻/ [_ id] / this_is_completely_meaningless它会将它们重定向到新闻/ [ _id] /富酒吧。