我正在尝试定义 Iron Router 路由以使用 slug:即。一个字符串 title
但空格被连字符替换。
我们希望它是 /news/breaking-news
,而不是 /news/breaking%20news
。
Router.map(function() {
this.route('news', {
path: '/news/:title'
})
})
要实现这一点,我们是否需要使用 slug 字符串创建一个新的文档字段 slug
并使用 path: '/news/:slug
?或者是否有更优雅的方法来避免这个冗余字段?
应用正在使用包 aldeed:simple-schema
、aldeed:collection2
和 dburles:collection-helpers
(如果有帮助的话)。
最佳答案
约束问题是从实际标题到 slug 的单向、不可逆转换(例如,“foo-bar”和“foo bar”都以相同的 slug,“foo-bar”,所以当你看到“foo-bar”时,你并不知道真正的标题是什么,所以你无法查找它)。因此,除非您可以对此进行控制(例如,按照您的建议将 slug 添加到文档中,或者对应用程序中的标题强制执行严格的无连字符策略),否则您将需要一种存储映射的方法。
解决此问题的一种可能方法是在 URL 中包含文档 ID 并有一个无意义的 slug,它可以由路由器本身填充:
Router.route('/news/:_id/:slug?', ...)
然后在实际路由中只使用_id。请注意,这允许您在 URL 中的 _id 之后放置任何您想要的内容,以便 'news/[_id]/foo-bar' 和 'news/_id/foo%20bar' 都转到同一页面,(news/[_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,但如果有人试图转到 news/[_id]/this_is_completely_meaningless,它会将他们重定向到 news/[ _id]/foo-bar.
关于javascript - 在 Meteor 的 Iron Router 中使用 Slugs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29131178/