Skip to content

About

Logic-less templating engine in Elixir (patterned after Liquid)

Resources

Stars

87 stars

Watchers

11 watching

Forks

 
 

Latest commit

 

History

243 Commits

Folders and files

Repository files navigation

Liquid Hex.pm Hex.pm Build Status

It's a templating library for Elixir. Continuation of the fluid liquid conversion.

Usage

Add the dependency to your mix file:

# mix.exs
defp deps do
  […,
   {:liquid, "~> 0.8.0"}]
end

You can either start the application directly:

Liquid.start

Or start it with your application:

# mix.exs
def application do
  [mod: {MyApp, []},
   applications: […, :liquid]]
end

Compile a template from a string:

template = Liquid.Template.parse("{% assign hello='hello' %}{{ hello }}{{world}}")

Render the template with a keyword list representing the local variables:

{ :ok, rendered, _ } = Liquid.Template.render(template, %{"world" => "world"})

For registers you might want to use in custom tags you can assign them like this:

{ :ok, rendered, _ } = Liquid.Template.render(template, %{"world" => "world"}, registers: %{test: "hallo")

The tests should give a pretty good idea of the features implemented so far.

Custom tags and filters

You can add your own filters and tags/blocks inside your project:

defmodule MyFilters do
  def meaning_of_life(_), do: 42
  def one(_), do: 1
end

defmodule ExampleTag do
  def parse(%Liquid.Tag{}=tag, %Liquid.Template{}=context) do
    {tag, context}
  end

  def render(output, tag, context) do
    number = tag.markup |> Integer.parse |> elem(0)
    {["#{number - 1}"] ++ output, context}
  end
end

defmodule ExampleBlock do
  def parse(b, p), do: { b, p }
end

and than include them in your config.exs file

# config.exs
config :liquid,
  extra_filter_modules: [MyFilters],
  extra_tags: %{minus_one: {ExampleTag, Liquid.Tag},
                my_block: {ExampleBlock, Liquid.Block}}

Another option is to set up the tag using: Liquid.Registers.register("minus_one", MinusOneTag, Tag) for tag Liquid.Registers.register("my_block", ExampleBlock, Liquid.Block) same for blocks; and for filters you should use Liquid.Filters.add_filters(MyFilters)

Global Filters

It's also possible to apply global filter to all rendered variables setting up the config:

# config.exs
config :liquid,
  global_filter: &MyFilter.counting_sheeps/1

or adding a "global_filter" value to context for Liquid.Template.render function: Liquid.Template.render(tpl, %{global_filter: &MyFilter.counting_sheeps/1}) (you need to define filter function first)

File systems

You can also set up the desired default file system for your project using the config.exs file

# config.exs
config :liquid,
  file_system: {Liquid.LocalFileSystem, "/your/path"}

Context assignment

Liquid.Matcher protocol is designed to deal with your custom data types you want to assign For example having the following struct:

defmodule User do
  defstruct name: "John", age: 27, about: []
end

You can describe how to get the data from it:

defimpl Liquid.Matcher, for: User do
  def match(current, ["info"|_]=parts) do
    "His name is: "<> current.name
  end
end

And later you can use it in your code:

iex> "{{ info }}" |> Liquid.Template.parse |> Liquid.Template.render(%User{}) |> elem(1)
"His name is: John"

Missing Features

Feel free to add a bug report or pull request if you feel that anything is missing.

todo

  • Fix empty check on arrays

About

Logic-less templating engine in Elixir (patterned after Liquid)

Resources

Stars

87 stars

Watchers

11 watching

Forks

Releases

Packages

Contributors

Languages