Radiant integration with another Rails app?

Loren J. wrote:

Read through the Readme in the extension now posted on RubyForge (see
Matt’s original post for address, etc) and you’ll find that the
“installation” is very straight forward and will be the same whether
it’s with a fresh Rails app or an existing one.

Give it a shot…

I read the README before posting, but it seemed to me like it was
explaining how to modify an existing Radiant app, rather than an
existing Rails app:

==================================================

  1. Edit RAILS_ROOT/config/environment.rb and change the following line

config.view_path = File.join(RADIANT_ROOT, ‘app’, ‘views’)

to

config.view_paths << File.join(RAILS_ROOT, ‘app’, ‘views’)
config.view_paths << File.join(RADIANT_ROOT, ‘app’, ‘views’)

The environment.rb file (RAILS_ROOT/config/environment.rb) in a stock
Rails app wouldn’t have any mention of ‘RADIANT_ROOT’

Am I misunderstanding the directions?

Loren,

Yes, it’s not quite straightforward at the moment to retrofit an
existing Rails app. These are the exact issues that need to be
worked out for the plugin version of Radiant, though. So, anything
you figure out should be applicable there. I’m guessing that there
might be a few minor changes to the Radiant code to get things
working cleanly in instance, gem and plugin modes.

Matt Parrish
http://www.pearware.org

Loren J. wrote:

You’re absolutely right, sorry I hadn’t looked closely enough.

You could gem install Radiant and generate an instance and then merge
the necessary bits from the environment.rb it generates into your
existing app.

If I get a chance I’ll try and determine what those necessary bits
are later today and email back what I learn.

Loren

So is the goal at this point to make it possible to install Radiant as a
plugin with the folder structure that John laid out?

plugins/
radiant/
init.rb
lib/
vendor/
radiant/ <<< an svn:external to trunk/radiant

Yes, it seems to me like that is the goal. Currently, Radiant takes
control of the files in config/ to do its initialization. It seems
like we would want to keep the Rails files as is, and do the
initialization in plugins/radiant/init.rb. I haven’t looked at it
yet, but I’m guessing there will be a few challenges to getting this
to work properly. One challenge I immediately see is getting
Radiant’s routes to coordinate with the Rails ones in config/routes.rb.

Matt Parrish
http://www.pearware.org

Oh, I guess I didn’t realize that vendor/radiant would be any easier
than vendor/plugins/radiant. How would that change things? If it’s
in vendor/radiant, don’t we have to get into config/environment.rb or
config/boot.rb to load radiant, whereas if it was in vendor/plugins/
radiant, then Rails would automatically start initializing it
(although I’m not sure at what part of the process it would do that)?

Matt

Why not keep Radiant in vendor/radiant? Then the startup scripts would
require less modification.

Sean

The stock environment.rb and boot.rb will load Radiant from
vendor/radiant automatically. The challenge of course, would be loading
the proper routes and adding the traditional app directories to the load
path. I think you guys already have that, no?

The other issue is that Radiant radically alters the bootup process and
needs to do so for the purpose of loading extensions. It’s my guess
that if you put it in vendor/plugins/radiant, things are going to be
much harder to hook up.

Sean

Okay, cool. As for the routes, my extension currently has the user
modify config/routes.rb a bit since /vendor/radiant/config/routes.rb
calls the Rails route initialization. If we could change it so that
Radiant hooks into that process differently, then the developer can
write config/routes.rb as is done traditionally. It doesn’t look
like the Rails guys have given an easy way to hook into that process,
although it could easily be a one line call to Radiant to load its
routes at the end of the ActionController::Routing::Routes.draw { |
map| } block. However Radiant’s /vendor/radiant/config/routes.rb
would need to change slightly to be like how extensions define routes.

Here’s the change I see. Instead of how Radiant currently does
config/routes.rb and vendor/radiant/config/routes.rb as

load File.join(RADIANT_ROOT, “config”, “routes.rb”)

and

ActionController::Routing::Routes.draw do |map|

Admin Routes

map.with_options(:controller => ‘admin/welcome’) do |welcome|

end

respectively. It could look like this:

ActionController::Routing::Routes.draw do |map|

Place for Rails Routes

map.with_options(:controller => ‘admin/welcome’) do |welcome|

RadiantRoutes.define_routes(map)
end

and

class RadiantRoutes
def self.define_routes(map)

Admin Routes

map.with_options(:controller => ‘admin/welcome’) do |welcome|

end
end

What do you think about making a change like that? We would just
need to make sure that config/routes.rb can see the RadiantRoutes
class. It wouldn’t affect the current Radiant usage, but would allow
for developers to work with config/routes.rb like normal. The
RadiantOnRails extension is like the first solution, except that I
have the user create a class RailsRoutes with a define_routes method
that my extension calls. I think the second solution here would be
preferred.

Matt Parrish
http://www.pearware.org

Yes, that’s basically what my extension is doing. But it does
require a slight change to config/routes.rb, because vendor/radiant/
config/routes.rb is where the ActionController::Routing::Routes.draw
{ |map| } block is. And I don’t think we can have that there and in
config/routes.rb

Matt Parrish
http://www.pearware.org

Yeah, that’s why I was saying perhaps a parse-and-eval method might
work:

  1. Load the “#{RAILS_ROOT}/config/routes.rb” file as text.
  2. Find and strip out the lines that contain the beginning and end of
    the block.
  3. eval the file in the local context of the define_routes block.

Not elegant, I know, but effective.

Sean

Yeah, that might work, but eeewwww! :slight_smile:

Wouldn’t it be better to modify Radiant a bit to have it be clean?
It’s really a fairly non-invasive change to Radiant.

Yeah, I was also thinking of the distribution issue… how do you make
it relatively painless to use.

Here’s another option – I imagine that the project’s lib/ directory
will be searched before the RADIANT_ROOT/lib directory, so you might be
able to replace the Radiant::Initializer class in there with
modifications. This should give you the hooks you need.

Maybe we should continue this discussion in the IRC channel? We’re
getting very back-and-forth.

Sean

Sean C. wrote:

The stock environment.rb and boot.rb will load Radiant from
vendor/radiant automatically.

You mean the stock environment.rb and boot.rb from a Radiant app, right?
Isn’t the idea to make RadiantOnRails act like a normal Rails plugin
that can simply be installed from the root of a Rails app with
‘script/plugin install radiant_on_rails’?

I believe this is why John laid out the folder structure the way he did:

John W. Long wrote:

plugins/
radiant/
init.rb
lib/
vendor/
radiant/ <<< an svn:external to trunk/radiant

That would be necessary to get auto-loading from a stock Rails app.
There seems to be a little bit of confusion in this thread (“Are we
adding Rails to a Radiant app, or Radiant to a Rails app?”), but I think
this snippet of Loren’s original post should clear things up:

Loren J. wrote:

putting Radiant in the vendor directory of an existing
full-scale Rails app and having it play nicely

I totally agree with Loren that it would be a much more common scenario
to want to retrofit a Rails app with Radiant. I’ve created more than a
few Rails apps (primarily e-commerce stores) where the site owner
eventually wanted more control over the copy. Update rhtml >> check-in

cap deploy gets quite tedious after a while. Retrofitting the app
with Radiant (in an unobtrusive way) would have been a great solution.

I think Matt and Loren’s cases are more about a tighter integration
between Radiant and the host application, including reusing Radiant
pages, layouts, and snippets in Rails. If you just want to add some
content management to an existing Rails application, there’s always the
Comatose plugin, which has been around for a while and is probably
better suited to that scenario.

Sean

Sean C. wrote:

I think Matt and Loren’s cases are more about a tighter integration
between Radiant and the host application, including reusing Radiant
pages, layouts, and snippets in Rails. If you just want to add some
content management to an existing Rails application, there’s always the
Comatose plugin, which has been around for a while and is probably
better suited to that scenario.

Sean

I spent a little bit of time with Comatose this week. It’s a cool
project, but a little bit too basic for my needs. I think we would agree
that Radiant is—in many ways—an unparalleled CMS.

Two things from my perspective with regard to what’s been said so far:

  1. In my understanding the standard plugin architecture as suggested
    by John gives us dead-simple Radiant plugin-ability to any forming or
    existing Rails app. This is probably the primary objective for my
    cases despite my whining about wanting to reuse my layouts, that and
    calling snippets / page parts in Rails views is a second priority for
    me.

  2. I don’t think we have to make the choice between “tight
    integration” of Radiant content into Rails views and simplicity of
    installation. They are different issues both with their own
    significant challenges, so it doesn’t make sense to try and achieve
    both in the same release. So, I think addressing the plugin
    architecture issues first is good. From that basis we can then work-
    out integration issues (snippet helpers, layout reuse, etc.)

I figure if we go that route we’ll have more people using Radiant as
a component of a larger Rails app sooner and therefore more input,
effort and ideas being contributed to making the content integration
stuff work as well and completely as possible.

  1. I’ve used Comatose in a few projects and each of those cases I’d
    rather have used a plugged-in version of Radiant instead. It’s a
    great project but I’d sure like to be leveraging my Radiant work and
    skills when I integrate. This also makes the transition with my
    clients from “we’ll start with a simple content site” to “now let’s
    build a custom app” less expense and painful. This is a common enough
    scenario for me.

I’ll put some more time into playing with Radiant installed as a
plugin this week and see what trouble I find. Looks like you’ve
gotten a good start on the right questions for me Sean and Matt. I’ll
report back on how far I get later this week.

Loren

Loren J. wrote:

…“we’ll start with a simple content site” to “now let’s
build a custom app” less expense and painful. This is a common enough
scenario for me.

I could see this being very common scenario for me as well. I’m moving
to a more iterative development process—hard-coded rhtml first phase,
then CMS second phase. I agree that the plugin would gain much more
exposure and feedback if we initially focused on making this a simple
process.

Since this is something I immediately need, I am very willing to pitch
in. I have to admit I’ve never made a plugin, but I have built about
seven production Rails apps.

If you point me to the right material, I could do some reading and
research this week and get up to speed on plugin development and help
out where possible.

Of course, if you feel it would be more a burden than a benefit to bring
on a plugin noob, that’s ok too.

Loren J. wrote:

I’ll put some more time into playing with Radiant installed as a
plugin this week and see what trouble I find. Looks like you’ve
gotten a good start on the right questions for me Sean and Matt. I’ll
report back on how far I get later this week.

Loren

Any luck, Loren?

Jed,

Thanks for checking. I actually gave the project several hours this
week and made some progress. I had a long conversation with Sean and
reviewed with him the issues I’ve ran into so far and the changes big
and small that may be required to make it work.

Feel free to email me directly and I’ll fill you in and see if we
might work together on any part of it. I’m not really ready to
publish my “findings” to the entire list quiet yet, though I’d like
to do just that shortly…

Loren
[email protected]

Here’s another option, one you may have considered already.

Extension routes are loaded before the Radiant routes and all of this is
taken care of by Radiant::Initializer. You could either extend
Radiant::Initializer or use the define_routes block in the extension to
load the primary routes.rb. I’m not sure whether you should parse,
process, and eval it or some other method, but it is conceivably
possible. I think it has to do with generators or rake tasks, but
Radiant does something similar to redefine some stock Rails stuff.

Sean