Widgets are everywhere on the web. These component-like regions on web pages deliver high levels of functionality. Though many of them are Ajax-dependent, having the same functionality as standard responses really expands the possibilities of our applications. To this effect, the gem merb-parts
subclasses AbstractController
, providing a new type of controller whose responses can be emebedded like partials within the actual response to a request.
Parts controllers are used in nearly the same way as the standard Merb controller. Here’s an example of a part placed in app/parts/
:
The most important thing to note is how the controller inherits from Merb::PartController
. Otherwise, nearly all the methods you might use in a controller, including render
, are available. Let’s take a look at the source code behind parts controllers in general:
We find that all subclasses of the parts controller are maintained in a set. Also important is the fact that part templates are located in a special directory, app/parts/views
. Each widget should have its own subdirectory for view files. Aside from their location, the views of parts are exactly like the views of the standard Merb controllers and are capable of using whatever templating engines are available.
When initialized, Merb parts connect with the web controller that has called them, duplicating their parameters and then merging in additional parameters. We’ll see where these parameters come from later on.
In order to make the URL helper available from inside our parts, the method url
has been set up to delegate directly to the Merb router. The interesting use of method_missing
also means that other methods coming directly from the web controller are available. In practice this means that to application developers, parts definitely feel just the same as proper web controllers.
Some methods, however, are better explicitly hooked. For this reason the WebController
mixin, which we saw included before, exists:
The invocation of a Merb part is intended to be done from inside a standard Merb view. To accomplish this, the method Controller#part
is mixed in when the dependency merb-parts
is included. The use of Controller#part
mimics the use of partials in that the only parameter it allows is a hash of options. Somewhere in the hash, however, a key-value pair specifying a parts controller and action must appear. By convention this is the first key set in the hash. The rest of the hash is merged into the original controller params to form the parameters for the parts controller. Below we invoke the GraphPart#index
action from inside an ERB template.
Let’s take a look at the mixin that makes this possible by adding in the method part
:
A curiosity of this method is the fact that it supports the passing of multiple part-action pairs, appending the results of each to the previous. Also note the initialization of each part and how the second parameter consists of the additional parameters that will be merged in.
You can generate the most typical files for individual parts with merb-gen
. Below we create a widget part for our application.
Merb parts, as another example of the subclassing of AbstractController
, capture the versatility of the framework. They allow us to compartmentalize parts of our application’s views into their own controllers and views. Thus it becomes possible to ensure that the logic and presentation layers of widgets stay separate. If you find yourself stretching the limits of regular partials or including seemingly unrelated widget code within controllers, parts are a great way to refactor your code and keep it DRY.
3.145.50.124