On 8/16/10 10:36 PM, Wes Gamble wrote:
All,
I have some custom models which need to be represented in Radiant
views, and I would like to be able to take advantage of standard Rails
partials, Rails form helpers, (e.g. all the good things about
ActionView).
I have a custom extension which holds all of my model information. I
have, in addition, created a Radius tag that is very close to
rendering a standard Rails partial using standard form helpers. I
can't really see the point in using the forms extension when the field
helper tags in it provide less functionality than standard Rails
helpers (and there is no support for textarea <input> elements).
Generally speaking, it seems that there are 3 options:
1) Do not use Rails partials at all, enhance the existing forms
extension to provide more ActionView helper-like functionality.
Basically, stay within the limits of Radiant.
2) Continue down the path I'm on, which is basically wrapping a Rails
partial with a Radiant tag (similar to this post from the Radiant
list: http://www.ruby-forum.com/topic/133878)
3) Figure out a way to hook into the Site controller and merge content
generated via both standard Rails mechanisms and Radiant (I know how
to hack around double render issues, etc.). I'm thinking that the
SiteController could basically become a mini-dispatcher when necessary
to run standard Rails actions, and ultimately render standard Rails
views/helpers, which can then be inserted into the HTTP response.
At the risk of being chastised for responding to my own post, I thought
I would update everyone on my progress.
Firstly, I forgot that <textarea> is it's own tag, so my assertion that
the forms extension was incomplete was of course, incorrect.
As for the three approaches, here's what I discovered - I ended up not
doing any of them.
1) Since custom Radius tags are executed only in the context of the
Radiant rendering process (which is bound to SiteController), to add all
the coolness I wanted would have been prohibitive.
2) I investigated creating a custom tag and learned a great deal, and
started looking into how I would initiate a standard Rails request from
within a SiteController action. But I ended up not really needing a
custom tag after all.
3) I did look into how to hook into the Site controller, thinking that I
could basically put a custom tag in a page part which would effectively
hold the URL for the action that I needed to run. Then I would just
initiate my standard Rails action during the standard SiteController
action processing of that page part. However, I ended up trying to
construct a valid Rails HTTP request object on the fly (which I had some
limited success at), which started to suck up too much time. Truth be
told, I would much rather that I be able to do it this way so that I
only incur a minimum of overhead (see CONS below).
What I really wanted to do was to execute the action in question as a
normal HTTP request and take the results and merge them with the Radiant
generated page. That way, all of the standard Rails magic would just work.
So here's what I ended up doing:
* I create a Javascript function (stored in Radiant) to generate my
Rails view (this is jQuery):
function generate_objection_form(obj_type_id) {
$.ajax({async: false,
url: '/admin/objection_instances/new',
data: {objection_type_id: obj_type_id},
complete: function(response)
{$('script').last().before(response.responseText)}})
}
Note that this Ajax call executes _synchronously_ so that the content is
rendered before the page returns.
* In each page that I need this form to appear, I add the following
<script> tag:
<script type="text/javascript">generate_objection_form(1)</script>
When the <script> tag is encountered, the Ajax call gets fired,
synchronously, and the content is inserted before the script tag that
made the call.
PROS:
* This is a standard Rails request, so no additional magic needed
* I can insert content at any point in the page using this scheme (I
need to modify the content insertion function to key off of an attribute
in the <script> tag - that way I don't have to depend on the positioning
of the tag like I'm doing now ($('script').last()).
CONS:
* This approach requires at least one additional request/response for
any custom content, granted it is lighter weight, most likely.
* My content templates are now split between Radiant (as
pages/parts/snippets) and the Rails app (as standard view templates).
It would be nice to be able to put the content into a page part and keep
it all in Radiant.
Hope this is of use to someone.
Thanks,
Wes