Ezamar

Intro

Ramaze allows you to use a variety of templating schema, including Markaby, HAML, Liquid, and a few others.

The default templating scheme is Ezamar.

Basic Concepts

When a request is made on a Ramaze app, the URL is mapped to a controller and a method on that controller.

For example,

http://example.com/foo/bar

might correspond the the method bar of an instance of the class FooController:

  class FooController < Ramaze::Controller
    def bar
       # some code
    end
  end
 

Now, to create a response to a given request, Ramaze will look for some combination of a controller method and a corresponding template file. Either a controller method, or a template file, or the combnination, will do.

Back to our example; if there is no corresponding template (i.e., template/foo/bar), then Ramaze will take the return value of bar and treat it as the template contents:

  class FooController < Ramaze::Controller
    def bar
       "I am bar.  Fear me!" 
    end
  end
 

We could also leave out the method bar, and simply have a template file to handle the request:

http://example.com/foo/baz

can be handled by template/foo/baz.xhtml:


<html>
  <p>I am baz</p>
</html>

Inline Templating

When a controller method creates a response without a template file it is referred to as inline templating.

The return value of method is run through the Ramaze templating engine and sent on its way.

External Templating

Sometimes creating all of your return content in a method is exactly the right thing, but if your final Web page is mostly pre-formatted text with variable substitution, then using an external template would be better.

The Ezamar templating engine uses the .xhtml file extension for external templates. By default, Ramaze expects to find templates under <your root dir>template/. You can change this, both at the application level and within any given controller.

Ezamar files must be XML. Despite the file extension, they do not need to be actual XHTML, but the template processing engine expects the template to be correct XML.

The template/ subdirectory hierarchy matches your controller mappings. MainController, by default, maps to the root path, so any templates for MainController methods go directly into template/.

For our example, templates for FooController would go into template/foo/. When Ramaze finds an external template it ignores the return value of the controller method. The content returned to the browser is the results of processing the external template.

Embedding Code in Templates

The content of an external template is assumed to be literal text to return to the client. This text, though, may contain special embedded content. There are two ways to embed code in templates. One is Ruby’s regular string interpolation syntax:


<html>
  <p>Right now, it is #{Time.new}</p>
</html>

In addition to normal Ruby code, such interpolated content may reference controller instance variables:

  class FooController < Ramaze::Controller

    def faz
      @time = Time.new.to_s
    end

  end

# ... and in template/foo/faz.xhtml

<html>
  <p> It is #{@time}</p>
</html>
 

Ezamar also understands a particular form of XML processing instruction that allows you to embed control structures:


<html>
  <p> It is #{@time}</p>

  <?r 10.times do  |x| ?>
  <p>I <3 Ezamar </p>
  <?r end ?>
</html>
 

So, basically: Ruby string interpolation for output, and Ezamar processing instructions for programmatic code.

Calling back into your controller

In addition to using controller instance variables, you can also call controller methods from your template.

  class FooController < Ramaze::Controller

    def faz
      @time = Time.new.to_s
    end

private

  def exclamation
    %w{ really certainly surely }.sort_by{ rand}.first
  end

  end

# ... and in template/foo/faz.xhtml

<html>
<p>I <3 Ezamar #{exclamation} </p>
</html>
 

Internal Templates, Revisted

In fact, we can consider an external template as an extension of the corresponding controller method; from Ramaze’s point of view, it matters not how the contents of the template were created. This means we can also use the processing instruction syntax within internal templates:

  class FooController < Ramaze::Controller

    def blop
     "<?r 10.times do  |x| ?><p>I <3 Ezamar \#{exclamation} </p><?r end ?>" 
    end

private

  def exclamation
    %w{ really certainly surely }.sort_by{ rand}.first
  end

  end

 

You should notice the backslash infront of the #{ ... ) string interpolation call. We need this so that the template string is not evaluated before being passed to the templating engine.

Now, we could avoid this by using single quotes to define the template string:

    def blop
      '<?r 10.times do  |x| ?><p>I <3 Ezamar #{exclamation} </p><?r end ?>'
    end

But with the double quotes we can make deliberate use of string interpolation to construct the template string that gets passed on to the template engine.

  # Pass in a value and use that to build the template string:
    def blip loop_count=nil
      "<?r #{loop_count || 3 }.times do  |x| ?><p>I <3 Ezamar #{exclamation} </p><?r end ?>" 
    end
 

This intertwingling is interesting, but could get messy. If we want to mix up code and markup, there’s another way we can do it

Elements

Ramaze provides a special class, Element, that allows us to define custom tags to use in our templates. So far, our examples have use some pretty sparse HTML. Let’s fix that.

Layouts

Partials