Table of Contents
1. What is Erector?
Erector is a Builder-like view framework, inspired by Markaby but overcoming some of its flaws. In Erector all views are objects, not template files, which allows the full power of object-oriented programming (inheritance, modular decomposition, encapsulation) in views.
2. Where are the docs?
3. Why use Erector?
- Markaby-style DOM builder domain language
- Your views are real classes, written in a real language, allowing
- Functional decomposition
- Composition, not partials
- Well-defined semantics for variables, loops, blocks
- Dependency injection via constructor params
- As little magic as possible while maintaining Rails compatibility
- yield works again (Markaby broke it)
- Very testable
- form_for ERB code is craaaaazy (not to mention the quagmire of options vs. htmloptions)
- Output is streamed, improving performance over string copy
4. Where are some examples?
We also have several examples checked in to the repository in the examples directory.
At RailsConf 2009 Alex whipped up a simple Sinatra + Erector + ActiveRecord webapp called Vegas. Caveat lector.
Currently we don't know of any open-source projects built with Erector so we can't show you working source code for a full Erector webapp. And client confidentiality keeps us from saying which of the Pivotal Labs project were built with Erector. But trust us, they're out there.
5. How does Erector stack up against Markaby?
We loved Markaby when we first saw it, since it transformed the gnarliness of Rails' ERB views into a clean, functional programming lanugage where views are primarily code with ways to emit HTML, rather than HTML with ways to hack in code. However, we soon realized Markaby had two main flaws:
- It didn't go quite far enough down the OO road -- Markaby views are still fragments, not classes
- Its use of instance_eval and capture, as well as a view's functional-but-not-quite-an-object nature, led to too much magic and made it very difficult to debug
Erector was conceived as a natural evolution of Markaby, but overcoming these two flaws. We think Erector can do pretty much everything Markaby can; if you find a counterexample, please let us know on the mailing list.
6. How does Erector stack up against HAML?
HAML is beautiful. But it suffers from the same design flaw (or, some would say, advantage) as every templating technology: views are not objects, and markup isn't code. But views want to do codey things like loops and variables and modular decomposition and inheritance, and every effort to wedge control logic into markup ends up smelling like a hack. There's always going to be some algorithmic idiom that's awkward in a template language. We figure, why deny it? Code is code. Embrace your true nature! Lick your screen and taste the code!
7. How do I use layouts?
Rails has a concept of layouts, which are essentially skeletons for a page, which get fleshed out by views. This is a powerful mechanism for rendering web pages; however, the mechanism Rails uses (via content_for and yield) is fundamentally incompatible with Erector's "just call the content method" design.
We recommend a slightly different approach, known officially as the Template Method Design Pattern: define a parent class (e.g. Page) and have your view widgets extend this class rather than directly extending Erector::Widget. The parent class implements content, and calls down to the child class to render sections or acquire information that's specific to that view.
8. How fast is Erector compared to ERB, HAML, etc.?
Initial benchmarking tests show that Erector is about 2x as fast as ERB and 4x as fast as HAML under typical conditions.
The main architectural benefits of Erector from a performance standpoint are:
Parsed by Ruby. Since Erector widgets are Ruby classes, the native-code Ruby interpreter compiles them during classload time, not a parser written in Ruby at runtime.
Append > Copy. Many templating systems are casual about whether a particular operation returns a string, or appends to an output stream. This can lead to wasteful copying and reallocation. In Erector, all operations concatenate their result to a single output buffer, even when calling nested widgets (via the
method). If you choose to, you can use Erector's
method for explicit string conversion, but by default we use the faster way.
Methods, not Partials. In ERB and HAML, modular decomposition is accomplished by separating reused code into separate template files. In addition to being aesthetically problematic, encouraging you to move related code into separate places, it also introduces a performance problem, since every partial may be rendered into a string. (Although sometimes it's not, which is just weird.)
We should point out, of course, that the choice of templating engines by itself is not what will make your application scalable. The effectiveness of your caching policy will dwarf that of your rendering engine in nearly all cases. But it's fun to know we've got a pretty fast horse in this particular race...
9. Why don't more people use Erector?
See Why don't more people use Erector? at Quora.