Thx for the radiant_layout tip!

Sent from my iPhone

On Oct 17, 2010, at 12:05 PM, swartz <[email protected]> wrote:

> Hey Wes,
> 
> Glad you got it working.
> I shall be attempting to re-integrate devise into an ongoing project
> as I've attempted earlier.
> 
> Just a few comments:
> Step4: It now makes sense. I was not careful at looking at what gets
> called and from where. This is where I gave up on my early attempt.
> Thank you!
> 
> Step5: You can use radiant_layout to use one of the layouts defined in
> radiant cms for your extension. For that you need shared_layouts
> extension. This cuts down on the having duplicated code for layout,
> which, in my case, remains the same as the main site.
> 
> On Oct 16, 5:03 pm, Wes Gamble <[email protected]> wrote:
>>   All,
>> 
>> I've spent some time getting Devise working as an authentication system
>> for my end users, and thought I would share how I got it to work.
>> 
>> 1) Because Radiant already has a User model, you have to set up Devise
>> to use a different model for authentication.  So, you should choose a
>> model name, and use that when you install Devise per the directions.  
>> For the purposes of the rest of this explanation, let's assume that the
>> model name is CustomUser.
>> 
>> 2) Do all of your setup for Devise for CustomUser, including setting up
>> the "devise_for" route (devise_for :custom_user, etc.).  I set up my
>> Devise route in my custom extension's routes.rb file.
>> 
>> 3) To protect all of the end-user content, you need to call the Devise
>> authenticate method somewhere as a before_filter on the SiteController
>> (I'm executing the line below in my custom application extension):
>> 
>>        #Use Devise to protect all Radiant-generated end-user content
>>        SiteController.class_eval do
>>        #Don't authenticate CSS or JS requests, as these will do redirects
>>        def devise_authentication
>>          authenticate_custom_user! unless params[:url] &&
>> params[:url].is_a?(Array) && (params[:url].include?('css') ||
>> params[:url].include?('js'))
>>        end
>> 
>>        prepend_before_filter :devise_authentication
>>      end
>> 
>> 4) Once you do this, Devise will be set up to be used to authenticate
>> against your end-user content.  But it won't work, because both Devise
>> and Radiant inject a method named "authenticate" directly into the
>> ApplicationController via module inclusion (luckily, they have different
>> method signatures, or I would have had a tough time figuring that out).
>> 
>> I attempted to force the segregation of these two authenticate methods
>> using nothing but fancy metaprogramming to try and change inheritance
>> hierarchies and what-have-you.  Ultimately, I decided that the solution
>> with the least customization (and thus, easiest to manage over time),
>> would be to statically bypass the ApplicationController provided by
>> Radiant in Devise.  So...
>> 
>> 5) Create a new controller named DeviseController that looks like:
>> 
>> class DeviseController < ActionController::Base
>>    layout 'devise'
>> end
>> 
>> I put mine in my custom extension's app/controllers directory, but you
>> can put it anywhere as long as it is loaded before any of the Devise stuff.
>> 
>> Also, notice that I built a custom layout for Devise (devise.html.haml)
>> that looks like my Radiant-managed layout for end-user content.
>> 
>> Yes, that means that changes to the layout within Radiant must be
>> repeated in this layout file.  However, I couldn't figure out a good way
>> to share the layouts (even using file_based_layout, I would have had
>> significant duplication to deal with - I decided to go the simplest route).
>> 
>> 6) Put a copy of the Devise gem into RAILS_ROOT (or
>> RADIANT_ROOT)/vendor/gems
>> 
>> 7) In vendor/gems/devise/app/controllers, change each of the five 5
>> Devise controller's class definitions so that they descend from
>> DeviseController, instead of ApplicationController, like so:
>> 
>> class ConfirmationsController < DeviseController
>> 
>> Note that each of the 5 controllers does:
>> 
>>    include Devise::Controllers::InternalHelpers
>> 
>> and this is where the conflicting "authenticate" method comes from.  But
>> now, because there's no more ApplicationController in the hierarchy,
>> there is no conflict.
>> 
>> 8) Unfortunately, the redirect on a sign_out does not redirect back to
>> the log in page by default (I need to resolve this), so I had to do the
>> following in my DeviseController:
>> 
>> def after_sign_out_path_for(resource_or_scope)
>>     new_custom_user_session_path
>> end
>> 
>> CAVEATS:
>> 
>> It is very important that the route file that pulls in the Devise route
>> executes before you attempt to use any of the Devise custom user
>> specific helpers.  The route configuration is what creates all of the
>> Devise helpers that are then included in various places.  If you cause
>> any helper files to be included before the Devise route is processed,
>> none of the custom helper methods will be available.
>> 
>> Wes
>> 
>> P. S.  It would be interesting to see if it made sense to use Devise for
>> all Radiant authentication (e.g. both end users and Radiant users), as
>> Devise has authentication for different scopes baked in from the start.

Reply via email to