I was looking into a way to send parameters to parts. A basic way to do this right now is this:
class Post < Application
def index
params[:part_param] = "This is part-time only"
@my_part = part(MyPart => :show) # can be included in view template
render
end
end
class MyPart < Merb::PartController
def show
@part_param = params[:part_param]
render # do something with @part_param in view
end
end
I find this kind of ugly and inconvenient, and I'd prefer to have a syntax like:
part(MyPart, :show, { :part_param => "This is part-time only" })
part(klass, method, opts={})
I patched Merb::Controller#part to add all passed opts to the params hash, so that the PartController action can access them.
So far so good. This works and has minimal overhead. The one thing I've been trying to hack in with no success so far is to get the controller action arguments syntax sugar that allows you to write
def show(stuff = "too much")
@stuff = stuff
end
instead of
def show
@stuff = params[:stuff] || "too much"
end
After my scavenger hunt through the controller/dispatching code, I've found out the following:
The magic for the action(args) sugar happens in AbstractController#call_action. All actions are routed through it. call_action uses an action_argument_list, which is a nested array that holds each controller.action's argument list and possible defaults, e.g. [[:x, 0], [:y]] => action(x=0, y). This array is built at startup from Merb::Server#load_application.
This is where I either don't understand the code well enough yet or it's a bug of sorts. Although PartControllers inherit from AbstractControllers, their actions are not included in the action_argument_list. Are they considered non-callable? Is there some scoping or security issue that I'm overlooking?
Let's discuss to see if this could become a patch or if the project has other plans for parts.
I think it would be cool to be able to call this:
part(TagCloud, :show, { :num_tags => 25 })