liquid 0.4.1

The liquid templating language for Rust
Documentation
# Writing plugins for liquid-rust

You can find the full example code [here](https://github.com/johannhof/liquid-plugin-example).

A core strength of liquid is that it has good support for writing external tags or blocks to support additional functionality.

In fact, the built-in blocks and tags are also hooked up using the public API!

> I'm gonna refer to both tags and blocks as "tags" from now on, for simplicity's sake.

This is a small guide that will walk you through the creation of a liquid tag. The tag that we want to create today is called `shout` and uppercases all text inside its brackets.

## Setting up

I'm assuming you'll want your plugin to live in a separate [crate]() instead of including it in application code. This means we'll have to make a new library with [cargo]()

    cargo init liquid-plugin-example

We'll need liquid as a dependency in our crate, so add the following to your `Cargo.toml`

    [dependencies]
    liquid = "0.3"

## First, a test

Before we get coding, let's write a test to see what we want to achieve and if it actually works already (hint: it won't). An example liquid code featuring our `shout` tag could look like this:

    {% shout %}
      Liquid!
    {% endshout %}

So we will add a test that follows the example from [the parse docs](https://cobalt-org.github.io/liquid-rust/liquid/fn.parse.html).

> This is a very high-level integration test. It's good for making sure everything works and saves us from playing around with liquid internals. However, if something goes wrong, it can be harder to pinpoint. For reference, the modules in the [liquid source] are unit-tested.

    extern crate liquid;

    #[test]
    fn it_works() {
        use std::default::Default;
        use liquid::Renderable;
        use liquid::LiquidOptions;
        use liquid::Context;

        let mut options : LiquidOptions = Default::default();
        let template = liquid::parse("{% shout %}Liquid!{% endshout %}", &mut options).unwrap();
        let mut data = Context::new();
        let output = template.render(&mut data);
        assert_eq!(output.unwrap(), Some("LIQUID!".to_string()));
    }

## Making a block

A proper liquid block is a struct that implements two traits: `Block` and `Renderable`.

> There is also a `Tag` trait for implementing tags

We're gonna make a struct that holds a `Template`, which is simply a container for multiple `Renderables`.

    struct Shout {
        inner: Template<'a>,
    }

### The Block trait

The `Block` trait is used by the liquid parser to convert a piece of liquid into the correct `Renderable` (see below);