Chapter 4. Views

While web services may need to serialize data only when sending responses, users typically interpret websites visually through HTML. Consequently, in order to better separate the formatting of data from its composition, the MVC paradigm pushes us toward the convenience of views. Within a Merb application, these concretely translate to using templates from which application responses are built.

Not all templates are formatted in the same way, though, and some are better suited than others for particular work. Consequently, Merb has since its beginnings been able to hook into different templating engines. Working off the Erubis and Haml engines, Merb enables the two most common template formats, ERB and Haml. We will cover both of these in this chapter as well as more specifically how to use them within Merb itself. As we’ll discover, Merb also enhances these templates in various ways, sometimes fundamentally as in the case of the BlockAwareEnhancer but most of the time more mildly through the inclusion of helpers and local variables.

Ultimately, views are a critical part of nearly every web application, but the Merb way of building applications has always been to minimize the amount of logic within them. While it’s easy to start employing Ruby to its full extent within views, we strongly advise considerable restraint while crafting views. Try pushing off relevant logic to helpers, controllers, or, better yet, models.

4.1 ERB

ERB, more properly known as eRuby, is the default templating system used by Merb. Because it does not make any requirements on the structure of the templates, ERB is amazingly versatile and can produce any textual format you may need for output, including, among other formats, HTML and XML. It is worthwhile to mention that nearly all the files produced by merb-gen are created using ERB templates.

Merb compiles ERB using the Erubis templating engine, an extremely fast implementation of ERB. You can use Erubis by itself outside Merb, and in order to introduce the basics of ERB, we’ll do just that.

4.1.1 Basic delimiters

The are two principal delimiters used within ERB: <% %> and <%= %>. If you have experience with JSP or ASP, you’ll find that their use is identical. Of the two, the first executes code, and the second executes and then inserts the result into the template ouput. The following template exhibits both:

image

We can excute the file using the command erubis. Here’s the result:

image

We are also able to pass in values for the variables from the command line using -c:

image

4.1.2 Removing whitespace

Unlike other ERB implementations, Erubis automatically trims whitespace from its execution-only delimiters. Output delimiters, however, include both leading and trailing whitespace. If necessary you can eliminate trailing newlines using the modified delimiter <%= -%>. This may not matter for an HTML file, but if you’re using ERB to format plain text or code, you’ll definitely appreciate its existence. As an example, the following script outputs the numbers 1 through 10 all on the same line. Note that we’ve included a final line break to compensate for its final suppression.

image

4.1.3 Comments

If you need to quickly cancel the effect of a line of ERB in a noncommittal way, the pound sign will do the trick. Because ERB interprets text delimited by <% %> as Ruby, squeezing in a # effectively puts a stop to both execution-only and output-delimited code:

<%#= "Foiled again!" %>

4.1.4 Merb’s block-aware enhancer

Unfortunately, standard ERB lacks the ability to execute multiline Ruby code split among multiple delimiters. In other words, the following simply will not work:

image

This may not seem problematic at first (who would ever need to do this?), but template helper methods often take blocks that sometimes cannot reasonably fit in one delimiter. Here’s a somewhat less contrived example of a helper using a block just to get the point across. Note that it does not work in standard ERB.

image

The work-around used by Rails (and most likely to be abandoned in the merge) has been to overload the use of execution-only delimiters through the inclusion of code in helper methods. This code first checks if the template being used is ERB or not and then forcefully outputs the result after interpreting the block.

The Merb team turned away from this solution unsatisfied, and Yehuda Katz instead crafted an Erubis enhancer as an alternative solution. The BlockAwareEnhancer found in the Merb core does precisely what it says it does, enhancing ERB so that it can spot and use multiline blocks. This does come with one slight inconvenience, though: The ending line of a block must use a special tail character on its directive, <% =%>. With this in mind, let’s rewrite the previous nonworking example to make it suitable for use in Merb:

image

Note that no alteration of the helper method was needed. Let’s take a look at the source code behind the enhancer to get a better feel for how it was accomplished:

image

The final method, add_expr_literal, is where the hard work starts. Erubis calls this method while converting input when it finds a Ruby expression that should be outputted. In other words, lines of ERB surrounded with <%= ... %> are handled by this method. You’ll notice that the if statement in this method checks to see if the code ends with the beginning of a block. If it does, then it withholds the closing of the concat parameter. The add_stmt2 method is then used to recognize the added delimiter <%=%> and will close the concat parameter if it spots one. This method is unfortunately not a part of Erubis, and some monkey patching of the method convert_input can be found elsewhere in the Merb source.

4.2 Haml

Haml is an alternative Ruby-infused templating language best suited for HTML and XML. Its focus is on terseness. If you are a web developer typically tortured with the verbosity of HTML and XML, this should come as a relief. Originally developed by Hampton Catlin, Haml is more recently maintained by Nathan Weizenbaum.

As with ERB, you can create Haml files outside Merb and compile them into output. As we go through some examples, you may want to use haml from the command line to do just that.

4.2.1 Tags

Tags in Haml are preceded by the percentage sign, %. You can use any of the standard HTML tags or dabble with your own creations as you please. Each Haml tag produces both open and close directives. For instance, the following:

image

produces the HTML output

image

The content of a Haml tag can appear directly after it on the same line, separated by some whitespace. Content not belonging to any tag can also appear simply by itself. Obviously this is not valid HTML, but Haml sets no limitation upon it. Below we demonstrate a first header tag with content inline and then some content on a second line belonging to no tag.

image

This compiles to

image

4.2.2 Indentation

Haml uses two-space indentation in order to indicate nesting. Any other form of indentation causes compilation errors, so watch out. Below we have nested a few common tags. Note that we can also choose to include tag content as if it were nested.

image

This compiles to

image

4.2.3 IDs and classes

Elements can also easily be given ID and class names. Prepend a # for IDs and a . for classes. Multiple classes can appear on a single element. Note that it is possible to use IDs and classes without explicitly specifying a tag, in which case a <div> tag is used. The lines

image

translate to

image

4.2.4 Attributes

If you need to add nonclass, non-ID attributes to tags, you can do so in Haml using curly braces immediately following the IDs and class names of an element:

%img{ :src => '/logo.png' }

This compiles down to

<img src='/logo.png' />

4.2.5 Interpreting lines

Lines that begin with - are interpreted as code. Their results are not outputted and are thus perfectly suited for the conditional appearance of markup or content. Because of the significance of indentation in Haml, the - is also used to represent the encapsulation of code. Consequently, no end keywords are needed or should be used. Below we set the content of an element based upon the time of day.

image

4.2.6 Outputting lines

Haml outputs the results of executed Ruby code when a = is used in place of -. The following example outputs the sum of two numbers:

image

Note that it is possible to simply append the = at the end of the tag specification. This is unlike the usage of the execution-only -.

4.2.7 Outputting string lines

Though the = automatically converts all objects to strings before outputting them to the template buffer, you’ll indubitably find yourself needing to format the content of some elements. The easiest way to do this is to use a string replacement like this:

image

For brevity, we can even drop the quotation marks and use a double equals sign, ==:

image

This also frees up the usage of both single and double quote marks, allowing us to use both without the need for escaping.

4.2.8 Sanitized lines

Haml has built-in support for sanitizing lines containing HTML-sensitive characters. This can prevent malicious (or accidental) HTML injections by mapping < and > to &lt; and &gt;. To do so, prepend either = or == with a &:

image

4.2.9 Preserving whitespace

You can use the tilde, ~, in place of the equals sign to preserve whitespace within elements where it’s needed. In particular, this applies to <pre> and <textarea> tags that are produced by Merb helpers. Below we simulate such a tag with a string.

~ "<textarea>One Line Two Lines</textarea>"

Note that the output below preserves this whitespace through the special character &#x000A;.

4.2.10 Filters

Haml is also able to support different template formats embedded within its usage. We can start a line (properly indented, of course) with a filter’s name in symbol form:

image

Notice how we used Ruby code interpolation in the final two filters to pass in instance variables for use with filters.

4.3 Merb view templates

The view templates of a Merb application are stored within the directory app/views/. Conventionally, each controller associates with a subdirectory, and each of its actions is handled by templates contained within. So, for example, the controller Users has its view templates located within app/views/users/, which may contain files like index.html.haml or show.html.erb. Such templates are used when we call the method render or display inside of the controller action:

image

Remembering that the controller and view code are tightly coupled within Merb, we can find the private method within the controller render mixin that when called by render looks for these template files. It’s called _template_for:

image

image

Note that this code first checks from a memoized list to see if a matching template has previously been found. If not, it proceeds to look for one in each of the template roots (of which there is typically only a full path to "app/views"), finding what it can. You may also spot the use of the pathname method /. Many of the methods shown above have been defined elsewhere, and the interested reader can discover a layering of AbstractController and Controller methods in that mixin method.

4.4 Partials

Partials are subtemplates used within view templates. To incorporate them, we can use the method partial within a view. Here we do so in both ERB and then in Haml:

image

The partial method takes as a first argument the path to the template. For example, above the path is 'users/preview'. There is one subtlety, however: Actual partial template files begin with an underscore. Thus, the path of the preview template is actually app/views/user/_preview.html.haml, possibly varying in template extension. The hash that forms the second and optional parameter on partial represents the local variables that are inserted and available to the partial.

4.5 Conclusion

It’s our recommendation that all Ruby web developers become comfortable with both ERB and Haml. While ERB’s versatility makes it a tool capable of every job, Haml’s brevity outshines ERB when targeting HTML and XML. As far as Merb is concerned, either works well, and as we’ve seen through the creation of the Erubis BlockAwareEnhancer, little of the core’s rendering code has to be aware of which templating engine is being used.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.163.175