ChiliProject is not maintained anymore. Please be advised that there will be no more updates.

We do not recommend that you setup new ChiliProject instances and we urge all existing users to migrate their data to a maintained system, e.g. Redmine. We will provide a migration script later. In the meantime, you can use the instructions by Christian Daehn.

Extending Liquid



You can define custom tags.

 1class MyTag < ChiliProject::Liquid::Tags::Tag
 3  # tag_name is the name of the tag which we got called with
 4  # markup are the attributes passed in parenthesis (as a single string)
 5  # tokens is the contents of the block of the tag was used as a block
 6  def initialize(tag_name, markup, tokens)
 7    @tag_name = tag_name
 8    @markup = markup
 9    @tokens = tokens
11    # always call super here!
12    super
13  end
15  # render is called when the tag is actually rendered.
16  # The passed context object hold many useful bits of data
17  # about the current context.
18  #
19  # What you return here will be outputted as a string.
20  def render(context)
21    "Hello World" 
22  end
25# now register the tag
26# first the name with which it should be made available to the author
27# then the tag
28# and then some options
29ChiliProject::Liquid::Tags.register_tag("my_tag", MyTag)

Everything you return from your render method will be handled as textile (or some other markup language as defined by the user) by default. It is thus subject to interpretation as markup input and escaping. If you want to return raw HTML from your tag, you have to register it with :html => true like this:

1ChiliProject::Liquid::Tags.register_tag("my_tag", MyTag, :html => true)


Parsing markup

There are various pre-defined regular expression constants for parsing the markup. At best, use simple grammars and avoid complex parsing here. Some examples can be found in source:lib/chili_project/liquid/tags as well as in the liquid gem itself

Rendering partials

The context object gives you access to the current view object. You can use it to render partials like this

1def render(context)
2  context.registers[:view].render :partial "stuff/items", :locals => { [...] }


Variables are an important concept in Liquid. Besides Drops they are the premier facility to provide content to a liquid context. Variables can always be overridden by authors, so don't depend on the exact pre-set value of the variable. For internal data, use the registers hash on the context object instead.

ChiliProject knows two types of pre-defined variables: static variables and lazy variables. Static variables are set to a static value before parsing. On each usage in the liquid document, they always return the exact same value (unless overwritten). Lazy variables are defined by a block of code that is evaluated on each read access of the variable. It can thus return more dynamic content.

Examples of both types can be found in source:lib/chili_project/liquid/variables.rb:

1ChiliProject::Liquid::Variables.register "tags" do
2  ::Liquid::Template.tags.keys.sort

This is a lazy variable. The passed block is evaluated on each "invocation" of the variable and returns an array of names of registered tags in the current context in this case.

A static variable can be created by just passing a static value:

1ChiliProject::Liquid::Variables.register "hello_world", "Hello there :)" 

Please make sure to properly sanitize your values and not return internal data to the outside world. . If required, you can pass a complex object. The to_liquid method will always be called. You can return a sanitized object representation there.


Drops are complex objects that can provide more advanced data types to the author.

Based on feedback from #604 the dev team decided that BaseDrop and the current implementation of Liquid should be seen as an "internal API". Thus it may change at any time while it is updated.