Liquex.Context (liquex v0.14.0)

Copy Markdown View Source

Context keeps the variable stack and resolves variables, as well as keywords. It also keeps configuration information needed to render a Liquid template, such as filters and the file system.

Variables are stored within a few different contexts which each have their own usage and meaning.

:environment

The environment stores the top level variables defined outside of the liquid templates. These are variables you want to predefine before rendering the templates. Note: these variables are not accessible within nested render tags.

:static_environment

The static environment is similar to the base environment. The difference is that it has a lower priority for reading than the environment and the variables defined in this context are accessible within nested render tags.

Use the static environment if you want global variables accessible across all render tags.

:scope

The scope is a stack of environments that keep track of variables within various scopes. For example, when entering a for loop, it creates a new scope and pushes it onto the stack. When exiting the for loop, all variables defined within that scope are removed.

Scopes have the highest precedence of all the different locations that store variables.

Examples

iex> context = Liquex.Context.new(%{hello: "environment"})
iex> Access.get(context, "hello")
"environment"

iex> context = Liquex.Context.new(%{}, scope: %{hello: "scope"})
iex> Access.get(context, "hello")
"scope"

iex> context = Liquex.Context.new(%{}, static_environment: %{hello: "static environment"})
iex> Access.get(context, "hello")
"static environment"

Summary

Functions

Assign a new variable to the context

Look up variable within the current scope. If the scope does not define the variable, it is then looked up in the environment. Lastly, if that fails, it falls back to the static environment.

Create a new Context using predefined variables map

Create a new context inheriting static environment and options

Callback implementation for Access.pop/2.

Pop the current scope off the scope stack and throw it away

Assign an error to the error logs

Push a new scope onto the scope stack

Types

t()

@type t() :: %Liquex.Context{
  cache: term(),
  cache_prefix: String.t(),
  cycles: map(),
  environment: map(),
  errors: [Liquex.Error.t()],
  file_system: struct(),
  filter_module: module(),
  private: map(),
  scope: Liquex.Scope.t(),
  static_environment: map(),
  timezone: nil | String.t()
}

Functions

assign(context, key, value)

@spec assign(t(), String.t() | atom(), any()) :: t()

Assign a new variable to the context

Set a variable named key with the given value in the current context

assign_global(context, key, value)

fetch(context, key)

@spec fetch(t(), any()) :: :error | {:ok, any()}

Look up variable within the current scope. If the scope does not define the variable, it is then looked up in the environment. Lastly, if that fails, it falls back to the static environment.

All variable look ups are indifferent to the key being a string or an atom. Either or can be used to save and store the variables.

get(context, key, default \\ nil)

@spec get(t(), any(), any()) :: any()

get_and_update(context, key, function)

@spec get_and_update(t(), any(), (any() -> any())) :: {any(), keyword() | map()}

Callback implementation for Access.get_and_update/3.

new(environment, opts \\ [])

@spec new(map(), Keyword.t()) :: t()

Create a new Context using predefined variables map

Returns a new context to store the current state of a liquid template during the render phase.

Options

  • :static_environment - An unchanging environment scope also accessible from nested render tags.

  • :scope - Initial scope with variables defined as if they were set within the liquid template.

  • :filter_module - Module that will be used for filtering

  • :file_system - File loading module

  • :cache_prefix - Prefix for cache keys, if you need separate partial caches for multitenancy or otherwise

  • :timezone - IANA name (e.g. "America/New_York") used by the date filter for 'now'/'today'/integer Unix timestamps. Requires a tzdata-backed TimeZoneDatabase configured via Calendar.put_time_zone_database/1. Defaults to nil, which means "use the host's local time" (same as Ruby's Time.now, honoring the TZ environment variable).

new_isolated_subscope(context, environment \\ %{})

@spec new_isolated_subscope(t(), map()) :: t()

Create a new context inheriting static environment and options

pop(context, key)

@spec pop(t(), atom() | binary()) :: {any(), t()}

Callback implementation for Access.pop/2.

pop_scope(context)

@spec pop_scope(t()) :: t()

Pop the current scope off the scope stack and throw it away

push_error(context, error)

@spec push_error(
  t(),
  struct()
) :: t()

Assign an error to the error logs

push_scope(context, new_scope \\ %{})

@spec push_scope(t(), map()) :: t()

Push a new scope onto the scope stack