December 07, 2009

It has Liquid::Blocks and it's called Magnetism

In my previous post about Liquid I never gave my project a name. Today it’s called Magnetism. It’s a pretty cool name for something that doesn’t work yet. I’ll be writing about Liquid assuming the audience is aware of what it and the Liquid syntax. Liquid consists of a few pieces. There are filters, drops, tags and blocks. This post will be going over blocks. Future posts will go over the other elements of Liquid as I add them to the Magnetism project.

What is a Liquid::Block

Liquid comes with a few blocks by default. You have if, unless and for to name a few. These wrap around template content.

1
2
3
4
5
6
7
8
9
10
11
12
<!-- the if block -->

{% if this_case %}
  do something in here.
{% endif %}

<!-- the for block -->
<ul>
{% for element in elements %}
  <li>{{ element }}</li>
{% endfor %}
</ul>

The prepackaged blocks are essential for template development, but I needed a few more so I dug through the Liquid documentation and the source code and got my hands dirty. I store my blocks in RAILS_ROOT/lib/magnetism/liquid and register them in RAILS_ROOT/config/initializers/magnetism.rb, but more on that later.

I’ve packaged my blocks in Magnetism::Liquid, but this isn’t necessary. This is how both cases would look.

1
2
3
4
5
6
7
8
9
10
11
12
13
# packaged
module Magnetism
  module Liquid
    class HTML < ::Liquid::Block
      # ...
    end
  end
end

# not packaged
class HTML < Liquid::Block
  # ...
end

The difference is at the line of inheritance. In my packaged class Liquid::Block is prefixed with ::, but that isn’t necessary in the second example because the class is not packaged. When creating a Liquid block two methods are called. There is the initialize method and render. At the moment I only needed render.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# lib/magnetism/liquid/html.rb
module Magnetism
  module Liquid
    class HTML < ::Liquid::Block
      def render(context)
        return <<-EOF
<!DOCTYPE HTML>
<html>
#{super}
</html>
        EOF
      end
    end
  end
end

The render method always has Liquid::Context passed into it. Even though I’m not using context in my render method I still needed to define it so render wouldn’t error. Within render the super method returns any code contained in your custom block.

1
2
3
4
5
6
<!-- index.liquid -->
{% html %}
<body>
  <h1>My Liquid Template</h1>
</body>
{% endhtml %}

This isn’t all Liquid blocks can do, but that’s all I’ve needed for Magnetism thus far. I’ll revisit Liquid blocks and explain Liquid::Context when I work on the comments form. Stay tuned for more!

Leave a Comment


Please wait...