テーマコンポーネントで既存のルートをリダイレクトする

既存の Discourse ルートをテーマコンポーネントでリダイレクトするには、api.modifyClass を使用してルートクラスを変更します。

詳細については、Ember のルーティングリダイレクトに関するドキュメントをご覧ください。以下は例です。

<script type="text/discourse-plugin" version="0.8"> 
    // タグルートを修正します。
    api.modifyClass('route:tag-show', {
        afterModel: function(tag, transition) {
            this._super(tag, transition);
            // 日曜日の場合、ID 20 のトピックにリダイレクトします。
            if (today.getDay() == 6) {
                this.replaceWith("/t/20");
            }
        }
    });
</script>

リダイレクトの場所や有無を決定するためにデータをロードする必要がある場合は、ルートフックがプロミスを返すようにする必要があります。これについては、Ember の非同期ルーティングに関するドキュメントで説明されています。以下は例です。

<script type="text/discourse-plugin" version="0.8">
    const ajax = require('discourse/lib/ajax').ajax;

    api.modifyClass('route:tag-show', {
        afterModel: function(tag, transition) {
            // この順序が重要であるようです。
            this._super(tag, transition);

            // ルートタグと 'canonical' タグの両方にタグ付けされた最初のオープンなトピックにリダイレクトします。
            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];
                    // 遷移先が遷移元と同じ場合の考慮が必要です。
                    // 遷移をキャンセルすることもできますが、ここではリダイレクトなしで処理を続行します。
                    if (!transition.from || transition.from.parent.name != 'topic' || transition.from.parent.params.id != topic.id) {
                        context.replaceWith("/t/" + topic.id);
                    }
                }
            })
            // 問題が発生した場合にキャッチし、(リダイレクトされない)ルートがフォールバックとして進行できるようにします。
            .catch(function() {
                console.log('Error loading topics by ajax in tag show route afterModel hook.');
            });
        },
    });
</script>
「いいね!」 8