Migration guide
This is the documentation for the latest version of Python Liquid (GitHub). Python Liquid strives for 100% compatibility with Shopify/liquid, the reference implementation.
Python Liquid2, a Python implementation of Liquid2, is an alternative Liquid template engine that deliberately deviates from Shopify/liquid in its syntax and rendering behavior.
Here we cover migrating from Python Liquid version 1.x to the latest version. See the Liquid2 migration guide if you're interested in switching to Liquid2.
New features
Other than improved error messages and some new standard filters (has
, find
, find_index
and reject
), there are no new features. Our goal with this release was to improve Python Liquid's API and improve compatibility with Shopify/liquid.
If you're interested in new features, take a look at Liquid2.
Python version support and dependencies
Support for Python versions 3.7 and 3.8 has been dropped. Both are now end of life.
MarkupSafe is now a required dependency. Previously it was an optional dependency.
Babel and pytz are now dependencies as internationalization and localization tags and filters are included in Python Liquid. They used to be available from a separate package.
API changes
Package-level functions
parse
, render
and render_async
are package-level functions that parse and render templates using the default environment. Where as before you might have done something like this:
You can now do:
Environment.parse
Environment.from_string
is now aliased as Environment.parse
. The old parse
method, which returned a list of nodes instead of a template, is now private.
from liquid import Environment
env = Environment(extra=True)
template = env.parse("Hello, {{ you }}!")
Environment.render
Environment.render
and Environment.render_async
parse and immediately render template source text without forcing you to explicitly create a new template.
from liquid import Environment
env = Environment(extra=True)
print(env.render("Hello, {{ you }}!", you="World"))
Template caching
The cache_size
argument to liquid.Environment
and liquid.Template
has been removed. Template caching is now handled exclusively by template loaders. See CachingFileSystemLoader
and CachingLoaderMixin
.
Expression caching
The expression_cache_size
argument to liquid.Environment
and liquid.Template
has been removed. Environment-level expression caching is no longer available as it does not play nicely with detailed error messages. If you need to cache parsing of Liquid expressions, it is now recommended to implement a cache per tag, where it makes sense to do so for your use case.
Template loaders
BaseLoader.get_source
and BaseLoader.get_source_async
have been changed to accept an optional context
argument and arbitrary keyword arguments as "load context". These new arguments replace methods get_source_with_context
and get_source_with_args
, which have been removed.
The value returned from get_source
, TemplateSource
, has also changed to be a named tuple of the form (text, name, uptodate, matter)
. It used to be (source, filename, uptodate, matter)
.
Template inheritance
We've added methods variables()
, variable_paths()
, variable_segments()
, global_variables()
, global_variable_paths()
, global_variable_segments()
, filter_names()
, tag_names()
and their async equivalents to liquid.BoundTemplate
. These are convenience methods for reporting variables, tags and filters using static analysis.
Custom tags
We've Changed Node.children()
to return a sequence of Node
instance only, and added expressions()
, template_scope()
, block_scope()
and partial_scope()
methods.
See liquid/builtin/tags for examples.
Exceptions
liquid.exceptions.Error
has been renamed to liquid.exceptions.LiquidError
.
liquid.exceptions.TemplateNotFound
has been renamed to liquid.exceptions.TemplateNotFoundError
.
liquid.exceptions.NoSuchFilterFunc
has been renamed to liquid.exceptions.UnknownFilterError
.
Render context
liquid.Context
has been renamed to liquid.RenderContext
and it's constructor arguments changed to require a instance of BoundTemplate
as its only positional argument instead of an instance of Environment
. All other arguments are now keyword only.
Tokens, streams and expressions
All tokens are now named tuples of the form (kind, value, start_index, source)
. They used to be (linenum, type, value)
, and sometimes standard tuples instead of named tuples.
The liquid.expressions
module has been removed in favour of a single TokenStream
interface (there used to be two) and more sane expression parsing functions or static methods. Here's a summary mapping from old expression parsing functions to the recommended new parsing functions/methods.
Old | New |
---|---|
tokenize_common_expression(str, linenum) |
liquid.builtin.expressions.tokenize(source, parent_token) |
*.tokenize(source, linenum) |
liquid.builtin.expressions.tokenize(source, parent_token) |
parse_common_expression(stream) |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_keyword_arguments(expr, linenum) |
liquid.builtin.expressions.KeywordArgument.parse(env, stream) |
parse_identifier(stream) |
liquid.builtin.expressions.Path.parse(env, stream) |
parse_unchained_identifier(stream) |
liquid.builtin.expressions.parse_identifier(env, stream) |
parse_string_or_identifier |
liquid.builtin.expressions.parse_string_or_path(env, stream) |
parse_unchained_identifier |
liquid.builtin.expressions.parse_name(env, stream) |
parse_boolean |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_nil |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_empty |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_blank |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_string_literal |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_integer_literal |
liquid.builtin.expressions.parse_primitive(env, stream) |
parse_float_literal |
liquid.builtin.expressions.parse_primitive(env, stream) |
Environment.parse_boolean_expression |
liquid.builtin.expressions.BooleanExpression.parse(env, stream) |
Environment.parse_filtered_expression |
liquid.builtin.expressions.FilteredExpression.parse(env, stream) |
Environment.parse_loop_expression |
liquid.builtin.expressions.LoopExpression.parse(env, stream) |