James L. skrev:
Can you give a little more detail of what you’re trying to do, and
maybe more importantly why you think you need to do it?
Ok. It’s yet another CM tool…
I have a tree of nodes (STI model using composition that references the
actual content models) with different node types representing pages
(which in turn is a collection of content items), folders, sites,
templates, images, links etc… Each node type is responsible of
rendering themselves to files at publish (when publish is “static”, ie
published to a server not supporting rails
).
So what I want to do is create a publish method in my NodesController
that simply calls publish() on the node in question without actually
having a clue about the node type (polymorphism in action). Some of the
nodes are pretty simple (images just goes straight into a file, a link
doesn’t get rendered at all since they are statically imported into the
page that uses them) but pages for example are more complex since the
templates relies on ERB. Other types, such as sites and folders, may
just control flow rather than producing files. If I create other node
types that also relies on ERB I want a generic way of handling this (the
node type creator shouldn’t have to fiddle with the NodesController).
Each of these node types may have a helper associated and in that case I
need to associate it with the current “scope”.
I can now invoke ERB through render_to_string() by passing a closure
from the controller into the models so they themselves can decide if
they want to use render_to_string() or not
Something like this:
def publish
Node.find(params[:id]).publish { |template, vars|
vars.each_key { |key|
self.instance_eval("@#{key} = vars[key]")
}
render_to_string :inline => template
}
render :text => “published node #{params[:id]}”
end
PageNode < Node
…
def publish
File.open(publish_path, “wb”) do |file|
#uses the “publish” block passed in
result = yield(page.page_template.content,
:view_mode => “show”,
:page_node => self,
:page => page,
:view_node => self)
file.write(result)
end
end
…
end
ImageNode < Node
…
def publish
#doesn’t care about the block passed in, just prints the data
File.open(publish_path, “wb”) { |file| file.print image.data }
end
…
end
What I would like is to somehow pass the helpers together with the other
params I pass into the block.
The point with doing all of this is that when adding a new node type I
only have to deal with the actual node type, not with all surrounding
framework code. I have one place to change/add things when I want to
change a node type, not several places where other might also be
affected (trying to keep it orthogonal)
Can you give a little more detail of what you’re trying to do, and
maybe more importantly why you think you need to do it?
Well, it might me something like that, I don’t know. I just want to keep
it modularized and having as few concerns in each place as possible. The
main problem is the requirement to publish to static files (doesn’t fit
very well with Rails itself maybe). I tried to use open-uri and call
nodes/show/[my_id] and just put that in a file but Webrick seemed to
deadlock or something (does it only support one request at a time??)
It would be fun to hear some feedback on the design as well though,
maybe you have some input for something simpler that I completely
missed.
/Marcus