Add custom route from initializer

plugins

#1

I came across a blog post by evil trout and some forum post that suggested I use the following…

Discourse.Route.buildRoutes(function() {

but I believe this method has been deprecated or removed at some point as attempting to use it currently results in an error as buildRoutes is undefined. Does anyone know what the proper way to do this is? Currently I am overriding the entire application route file and that just doesn’t seem right to me.


Extending nested resource routes
(James Kiesel) #2

Babble does this with a separate route-map file, with a map function in it, which appends the routes to the existing map:

https://github.com/gdpelican/babble/blob/master/assets/javascripts/discourse/babble-route-map.js.es6


Add sub route such as users/:username/<subRoute> in a plugin
#3

Thanks, unfortunately this nets me the same result i have using just a normal export, when declaring entirely new resources and routes it’s fine but when extending an existing one such as user for example what ends up happening is that it replaces the user resource with what you define instead of extending it. Meaning you have to include the entire this.resource('user', block into your map or your normal user routes won’t work.

export default function() {
  this.resource('user', { path: '/users/:username' }, function() {
    this.route('my_new_route');
    this.route('my_second_new_route');
    this.resource('userActivity', { path: '/activity' }, function() {
      var self = this;
      _.map(Discourse.UserAction.TYPES, function (id, userAction) {
        self.route(userAction, { path: userAction.replace('_', '-') });
      });
    });

    this.route('badges');
    this.route('notifications');
    this.route('flaggedPosts', { path: '/flagged-posts' });
    this.route('deletedPosts', { path: '/deleted-posts' });

    this.resource('userPrivateMessages', { path: '/messages' }, function() {
      this.route('mine');
      this.route('unread');
    });

    this.resource('preferences', function() {
      this.route('username');
      this.route('email');
      this.route('about', { path: '/about-me' });
      this.route('badgeTitle', { path: '/badge_title' });
      this.route('card-badge', { path: '/card-badge' });
    });

    this.resource('userInvited', { path: '/invited' }, function() {
      this.route('show', { path: '/:filter' });
    });
  });
}

vs

export default {
  resource: 'app',
  map() {
    this.resource('user', { path: '/users/:username' }, function() {
      this.route('my_new_route');
      this.route('my_second_new_route');
      this.resource('userActivity', { path: '/activity' }, function() {
        var self = this;
        _.map(Discourse.UserAction.TYPES, function (id, userAction) {
          self.route(userAction, { path: userAction.replace('_', '-') });
        });
      });

      this.route('badges');
      this.route('notifications');
      this.route('flaggedPosts', { path: '/flagged-posts' });
      this.route('deletedPosts', { path: '/deleted-posts' });

      this.resource('userPrivateMessages', { path: '/messages' }, function() {
        this.route('mine');
        this.route('unread');
      });

      this.resource('preferences', function() {
        this.route('username');
        this.route('email');
        this.route('about', { path: '/about-me' });
        this.route('badgeTitle', { path: '/badge_title' });
        this.route('card-badge', { path: '/card-badge' });
      });

      this.resource('userInvited', { path: '/invited' }, function() {
        this.route('show', { path: '/:filter' });
      });
    });
  }
};

Both net you the same result, though the latter one has the added weirdness of appending whatever you declare as your resource before whatever you include in your routes. So /user/activity would now become /app/user/activity

This isn’t a huge issue for my use case but I predict conflicts with more advanced plugins if you have a discourse installation and both are modifying the user routes for example.


(James Kiesel) #4

Not quite sure I follow; the above example is adding a ‘chats’ route to an existing ‘admin’ resource, using the ‘resource’ keyword. (ie, adding admin/chats and admin/chats/:id to an app where the ‘admin’ namespace exists and already has routes in it.

Did you try

resource: 'user'
map() {
  this.resource('myRoute', { path: '/my_route' })
}

??


#5

Yeah, in that instance it simply doesn’t register the route like i’d expect, for example I’m accessing my route like

{{#link-to 'user.myroute'}}

and when using your example above the result is that user.myroute simply doesn’t exist. Where as using my example above, including the entire user resource it does.


#6

For those of you that didn’t get this to work. Here’s a more detailed mapping that worked for me.

export default {
  resource: 'user',
  path: 'users/:username',
  map() {
    this.resource('music', { path: '/music' });
  }
}

Explained here: