I need to include another helper module apart from the normal two (ApplicationHelper and [controllername]Helper). The inclusion needs to be dynamic and based on external parameters (ie what helper that get included differ from request to request). Is it possible? How? /Marcus
In your controller, after your class declaration helper :modelname Although if you''re goign to have things that exist across multiple models and controllers, wouldn''t it make more sense to extrapolate those up to a higher level? On Feb 12, 2006, at 4:39 AM, marcus wrote:> I need to include another helper module apart from the normal two > (ApplicationHelper and [controllername]Helper). The inclusion needs > to be dynamic and based on external parameters (ie what helper that > get included differ from request to request). > > Is it possible? How? > > /Marcus-- John Athayde bobo@meticulous.com Meticulous | www.meticulous.com (work) Rotoscope | www.rotoscope.com (sound: rock band) Boboroshi & Kynz | www.boboroshiandkynz.com (sound: electronic) Personal Weblog | www.boboroshi.com (play) "Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety." - Benjamin Franklin (1706-1790) Reply of the Pennsylvania Assembly to the Governor November 11, 1755 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060212/748149f1/attachment.html
John Athayde skrev: > In your controller, after your class declaration > > helper :modelname > > Although if you''re goign to have things that exist across multiple > models and controllers, wouldn''t it make more sense to extrapolate those > up to a higher level? The problem I have is that I need "polymorphic" helpers and what helper(s) to use is request based (both parameters and database data). Your approach and the other one you propose is kind of static and I can''t override on a request by request basis (or it''ll probably be on an invocation by invocation basis of render_to_string() even). Although I think I can probably come up with something now that I see your proposal. But if someone can give me a hint of something to use inside a method then I''ll be very happy... /Marcus
On 2/12/06, marcus <m-lists@bristav.se> wrote:> John Athayde skrev: > > In your controller, after your class declaration > > > > helper :modelname > > > > Although if you''re goign to have things that exist across multiple > > models and controllers, wouldn''t it make more sense to extrapolate those > > up to a higher level? > > The problem I have is that I need "polymorphic" helpers and what > helper(s) to use is request based (both parameters and database data). > Your approach and the other one you propose is kind of static and I > can''t override on a request by request basis (or it''ll probably be on an > invocation by invocation basis of render_to_string() even). > > Although I think I can probably come up with something now that I see > your proposal. But if someone can give me a hint of something to use > inside a method then I''ll be very happy...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?>From the details given so far, I''m thinking that there''s a design flawin here somewhere. -- James
James Ludlow 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
marcus wrote:> 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??)Rails, by default, only handles one request at a time. In FCGI and SCGI environments this translates to one request per FCGI/SCGI process 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.It sounds as if you should be passing an object around, encapsulating any helpers required and any stream to which output is being done. Then you could choose which class to instantiate for this purpose according to the request being handled. Are you familiar with the Visitor pattern? http://en.wikipedia.org/wiki/Visitor_pattern regards Justin
On 2/12/06, marcus <m-lists@bristav.se> wrote:> I need to include another helper module apart from the normal two > (ApplicationHelper and [controllername]Helper). The inclusion needs to > be dynamic and based on external parameters (ie what helper that get > included differ from request to request). > > Is it possible? How?Filters. The request based requirement seems to make your controller a no-brainer. The controller then conditionally adds new instance methods to the appropriate objects. Seems sound. -- Seth Thomas Rasmussen http://sethrasmussen.com/