To redirect an existing Discourse route in a theme component, you can use api.modifyClass
to modify the route class.
More information can be found in the Ember documentation on routing redirection. Here’s an example:
<script type="text/discourse-plugin" version="0.8">
// Modify the tag route.
api.modifyClass('route:tag-show', {
afterModel: function(tag, transition) {
this._super(tag, transition);
// If it's Sunday, redirect to the topic with id 20.
if (today.getDay() == 6) {
this.replaceWith("/t/20");
}
}
}
</script>
If you need to load data to decide where or whether to redirect, you need to have your route hook return a promise, as discussed in the Ember documentation on asynchronous routing. Here’s an example:
<script type="text/discourse-plugin" version="0.8">
const ajax = require('discourse/lib/ajax').ajax;
api.modifyClass('route:tag-show', {
afterModel: function(tag, transition) {
// It seems to matter that this comes first.
this._super(tag, transition);
// Redirect to the first open topic that is tagged with both the route tag and the 'canonical' tag.
var path = `/tags/intersection/canonical/${tag.id}.json`;
const context = this;
return ajax(path).then(function(result){
var topics = result.topic_list.topics.filter(function(topic) {
return !topic.closed ;
});
if (topics && topics.length > 0) {
var topic = topics[0];
// You need to consider the case where the destination is the same as the origin.
// You could cancel the transition, but here we allow it to proceed without a redirect.
if (!transition.from || transition.from.parent.name != 'topic' || transition.from.parent.params.id != topic.id) {
context.replaceWith("/t/" + topic.id);
}
}
})
// Catch any problems so that the (non-redirected) route can proceed as a fallback.
.catch(function() {
console.log('Error loading topics by ajax in tag show route afterModel hook.');
});
},
});
</script>