So I've got this project where I would like Radiant to render the initial page, but do subsequent updates to various divs via AJAX. I decided this because I don't want a separate but identical layout files within Radiant and the app/views/layout of my extension. I won't be the one to use this CMS once it is installed and if the user has to come back to me for minor layout changes once things are in place, that won't be nice.
I created an extension with the idea that I would create a tag for each div and define them to render the same partials that my the AJAX calls return, just with some default parameters. I imagined I would use render_component or maybe render_partial but quickly found there is no controller to make these accessible from the tag definition context. Without partials and without helpers like form_remote_tag and link_to_remote, I found myself putting lots of raw html and javascript (Prototype Ajax.request methods) in each tag block. Pretty nasty, so I scrapped that. Another solution would be the ability to render snippets from my controller instead of the usual views. I've looked at Radiant on Rails but support for processing Radiant tags while doing such output is still a work in progress. Even if tag processing is finished soon, there is still the issue of getting to Prototype/AJAX helper methods into those snippets. I really like the idea of using snippets via my controller though, if it were combined with an extension that exposes rails Form/Prototype/Javascript helpers via Radiant Tags, that could maybe work, without introducing that complexity into the core Radiant code. For example, instead of my controller/view outputting an entire AJAX sortable table, if I could define it as a snippet w/ the appropriate AJAX helpers in place as Radiant tags, the end user could then tweak considerably more, adding/dropping columns or changing class/id/css information. I've already created radiant tags to access and iterate over rows in my model so I think this would be a nice fit. Which brings me back to my original approach, accessing rails view/controller helpers from an extension tag block. I've read a few posts where people were trying to do this, but they all have their problems. Below are my experiences with various ways I've tried to get around this. ------------------------------- Mental Tags - FormTagHelper? http://www.ruby-forum.com/topic/104454#232664 This could allow tags to use rails helpers, thought it may be buggy. But without the ability to render snippets from my controller, it is only a half solution as my the AJAX responses from my controller will need to output snippets, which RadiantOnRails does, but without processing Radiant tags, so it would only work for the initial request served up by Radiant. I could use a separate partial for the AJAX responses but I don't want my user making changes in the CMS and finding the AJAX responses look different. ------------------------------- ActionView helpers in a behavior - I think I got it! http://www.ruby-forum.com/topic/73437 Same issues as above, possible bugs, no controller access to output snippets after tag expansion. ------------------------------- RJS/Tracking Controller through Radiant Extension? http://www.ruby-forum.com/topic/107811#244757 Requires modifying a page's process method to look for AJAX requests, but I thought my extension's controller can already receive requests directed to it, so I don't see the point. ------------------------------- [Radiant] Can you use controllers/views within a tag http://lists.radiantcms.org/pipermail/radiant/2007-February/003407.html Ahh, bring a controller instance into my Tag module/mixin. This may be my best solution at this point. This would allow me to render entire divs using single tags that output partials using my controller - the same partials that my AJAX responses will continue to return. No need to import rails view helpers into my tag module, and no need to render snippets from the controller with tag processing. Not as as flexible as I would like, but this approach doesn't require me to duplicate the site layout in app/views/layouts. The sample code in the above post doesn't work as is, it needed a few changes, which the the guys in #ruby-lang help me come up with. Posted below, with asterisks by the added/changed lines - def activate * require 'application' * SiteController.class_eval do def show_uncached_page(url) puts '!!!in show_uncached_page' @page = find_page(url) unless @page.nil? @page.process_controller(self) @cache.cache_response(url, response) if live? and @page.cache? @performed_render = true else render :template => 'site/not_found', :status => 404 end rescue Page::MissingRootPageError redirect_to welcome_url end end * Page.class_eval do attr_accessor :controller def process_controller(controller) @controller = controller process(controller.request, controller.response) end end Page.send :include, MemberDirectoryTags end So after that, from your tag definition, you just call - tag.globals.page.controller.render_component_as_string :controller => "member_directory", :action => "sortable_table" Right? Nope. render_component_as_string is protected. ------------------------------- So I tried something different - >From my controller (MemberDirectoryController) - def sortable_table_as_string render_component_as_string :controller => "member_directory", :action => "sortable_table", :params => { :person => "david" } end >From my tag definition - tag 'member_test_tag' do |tag| @controller = MemberDirectoryController.new puts @controller @controller.sortable_table_as_string end well when I use <r:member_test_tag /> this displays in my browser - can't dup NilClass Through using some output statements I found this happens during render_component_as_string in my controller. I'm guessing the controller needs more initialization than just calling new on it. ------------------------------- And finally I tried.. (asterisks on lines added over prior example) def activate require 'application' SiteController.class_eval do def show_uncached_page(url) puts '!!!in show_uncached_page' @page = find_page(url) unless @page.nil? @page.process_controller(self) @cache.cache_response(url, response) if live? and @page.cache? @performed_render = true else render :template => 'site/not_found', :status => 404 end rescue Page::MissingRootPageError redirect_to welcome_url end * def unprotected_render_component_as_string(options) * render_component_as_string options * end end Page.class_eval do attr_accessor :controller def process_controller(controller) puts '!!!in process_controller' @controller = controller process(controller.request, controller.response) end end Page.send :include, MemberDirectoryTags end Like my past attempts but I attempted to get around the protected render_component_as_string and half-initialized controller by adding a public instance method to SiteController called unprotected_render_component_as_string(options) to expose the protected method. And in my tag definition file I put: tag.globals.page.controller.unprotected_render_component_as_string :controller => "member_directory", :action => "sortable_table" The <r:member_test_tag /> produced the error "interning empty string" Below is the framework trace - /usr/lib/ruby/gems/1.8/gems/radiant-0.6.1/lib/login_system.rb:16:in `intern' /usr/lib/ruby/gems/1.8/gems/radiant-0.6.1/lib/login_system.rb:16:in `authenticate' Looks like an authentication issue? I don't really know. ------------------------------- Well, that is it. I've outlined this quest to get things working with AJAX so it will be available as a use case, and maybe help the devs decide how to go forward with official changes to accommodate such apps. I very much like Radiant for non-ajax use, I'll be keeping an eye on it for future projects as well. If someone could point out how to access render_component_as_string from my tag definition I'd be grateful. I've got to move on with this project so I will be doubling up on my layouts for now, but if there is a way, I'd like to know. -- Posted via http://www.ruby-forum.com/. _______________________________________________ Radiant mailing list Post: [email protected] Search: http://radiantcms.org/mailing-list/search/ Site: http://lists.radiantcms.org/mailman/listinfo/radiant
