Allow users request access to private categories: rendering custom template on exception


(Jose Rilla) #1

Hi all,

I’m working on this plugin which adds a setting to allow showing read-restricted categories in the category list.

This is already working (you can check the code in the Github repo), but now, as a next step, I want to show a custom view when a user with no access clicks on a restricted category.

My intention is to add a message to that view explaining that the category is private and encourage the user to register and request access to the category.

The way I’m doing this is adding a new NoAccessToCategory exception that is thrown whenever a user tries to access the restricted category, and now I’m trying to rescue from this category and show a custom template.

This is what I’ve done so far:

  1. Declare the new exception:
 # lib/discourse.rb
class NoAccessToCategory < StandardError; end
  1. Tweak CategoryGuardian so it throws NoAccessToCategory instead of NotFound:
# lib/guardian/category_guardian.rb
def ensure_can_see!(obj)
   raise Discourse::NoAccessToCategory.new("Can't see #{obj}") unless can_see?(obj)
end
  1. Rescue in ApplicationController:
  # app/controllers/application_controller.rb
  rescue_from Discourse::NoAccessToCategory do
    if (request.format && request.format.json?) || (request.xhr?)
      # No idea what to do here
    else
      render_to_string status: 200, layout: 'no_ember', formats: [:html], template: '/exceptions/no_access_to_category'
    end
end
  1. Build the view:
  # app/views/exceptions/no_access_to_category.html.erb
  <h1>No access to this category</h1>
  <div>
     You don't have access to this category
  </div>

This is working when I browse directly to a restricted category url (i.e. no AJAX request), but it’s not working when the category is accessed by clicking through the Ember frontend.

I’m completely unfamiliar with Ember (I come from a Rails background), and I would be very grateful if someone could give me some pointers as to how should I implement this.

Once it’s done, I will of course release this and hopefully will be of some use for other users – I’ve seen this requested in a couple of threads: here and here.