[Updated: added instructions “If you are using a widget in rails, you now need to inherit from RailsWidget”]
Erector has been around for almost 2 years now, but we’ve always been a little reluctant to market it heavily. One reason has been that the API was a little inelegant. Another is that Rails integration wasn’t as seamless as we’d like.
With today’s release of version 0.6.3, we have hopefully fixed both of those problems. With the new RailsWidget we’ve got a clean separation between core Erector functionality and the magic we need to make it work with Rails. We’ve renamed “render” to “content” so we don’t conflict with the standard Rails render method. And we’ve changed the API for smoother lifecycle management — the constructor is about initializing the widget, and the refurbished “widget” method is about setting it up to emit its HTML.
The bad news is that you’ll have to change your existing code. The good news is there’s an update guide, which you’ll find below the fold in this blog post.
(Why 0.6.3 and not 0.6.0? Because we had to work through some glitches in the new deploy process with GitHub and Jeweler and whatnot. We’re only human…)
Erector 0.6.0 Announcement
This release is the first major API change to Erector. It will definitely break
existing code. Sorry about that, but we promise it’ll be cleaner afterwards.
Quick Update Guide
Rename ‘def render’ to ‘def content’ in all your widgets
If you are using a widget in rails, you now need to inherit from
RailsWidget to get helper goodness
Change MyWidget.new(helpers, assigns, output) to just
To render a widget from inside another widget, use
widget MyWidget, :foo=>2
widget MyWidget.new(:foo => 2)
If you want your variables to have attr_readers, use ‘needs’
If you want your widgets to be more self-documenting, use ‘needs’
Major API changes
“new” and “to_s” have been changed to clarify the lifecycle of a widget,
so “new” accepts permanent state (”assigns” variables) and “to_s” accepts
temporary, rendering state (output stream, helpers, and prettyprinting).
This lets you do things like make collections of widgets in once place in
your code and render them in another place.
Renamed “render” to “content”, which removes confusion/ambiguity with
Rails’ “render” method and concept, and also allows “render :partial” to
be made to work (though we’re not sure if that totally works yet).
To render a widget from outside code, the pattern is:
w = DateWidget.new(:when => Time.now, :title => "Nap Time") puts w.to_s(:helpers => some_rails_view)
To render a widget from inside another widget:
def content # first way... pass class and assigns widget DateWidget, :when => Time.now, :title => "Nap Time" # second way... pass instance widget DateWidget.new(:when => Time.now, :title => "Nap Time") end
Using “widget” will improve performance over calling “raw foo.to_s” or
whatever since it reuses the same output stream.
To declare variables — and raise an exception when one is not provided:
class JohnLennon < Erector::Widget needs :love end
Formerly, every ‘assigns’ variable had an attr_reader defined for it. Now,
only variables declared with ‘needs’ get attr_readers.
Removed Widget#to_s caching, which fixed indentation issues.
BUGFIX: Indentation level is now correctly propagated to nested widgets.
Erector’s Rails support strategy has changed. The released version of
Erector only supports the latest stable Rails version (currently 2.3.2).
If you need support for earlier versions of Rails, there are separate Git
branches for each one, but we will not be in the habit of keeping these up
to date with the latest features and patches. If someone wants to do a
merge to a prior Rails branch, Brian will be happy to help :-)
About the Author