Skip to main content

micro-liquid


Table of Contents

Install

pip install micro-liquid

Example

from micro_liquid import Template

template = Template("Hello, {{ you }}!")
print(template.render({"you": "World"}))  # Hello, World!

About

Micro Liquid implements minimal, Liquid-like templating. You can think of it as a non-evaluating alternative to f-strings or t-strings, where templates are data and not necessarily string literals inside Python source files.

Full-featured Liquid (Python Liquid or Shopify/liquid, for example) caters for situations where end users manage their own templates. In this scenario, it's reasonable to expect some amount of application/display logic to be embedded within template text. In other scenarios we'd very much want to keep application logic out of template text.

With that in mind, Micro Liquid offers a greatly reduced feature set, implemented in a single Python file, so you can copy and paste it and hack on it if needed.

Here, developers are expected to fully prepare data passed to Template.render() instead of manipulating and inspecting it within template markup.

What's included?

Micro Liquid support variable substitution:

Hello, {{ some_variable }}. How are you?

Conditional expressions:

{% if some_variable %}
  more markup
{% elsif another_variable %}
  alternative markup
{% else %}
  default markup
{% endif %}

And looping:

{% for x in y %}
  more markup with {{ x }}
{% else %}
  default markup (y was empty or not iterable)
{% endfor %}

Micro Liquid expressions can use logical and, or and not, and group terms with parentheses.

{% if not some_variable and another_variable %}
  some markup with {{ some_variable }} and {{ another_variable }}.
{% endif %}

Short circuit evaluation works too, with last value semantics. Here you might use a string literal.

Hello, {{ user.name or "guest" }}!

Control whitespace before and after markup delimiters with - and ~. ~ will remove newlines but retain space and tab characters. - strips all whitespace.

<ul>
{% for x in y ~%}
  <li>{{ x }}</li>
{% endfor -%}
</ul>

What's not included?

If you need any of these features, and many more, try Python Liquid or Python Liquid2 instead.

  • Assignment, captures and snippets (include and render). Or any tag other than if and for.
  • Relational operators like == and <.
  • Membership operators like contains and in.
  • Filters.
  • Literal Booleans, integers, floats or null/nil/None.
  • {% break %} and {% continue %} tags.
  • Nested variables.
  • forloop helper variables.
  • for tag arguments like limit and reversed.

Other notable behavior

  • We use Python truthiness, not Liquid or Ruby truthiness.
  • Any Iterable can be looped over with the {% for %} tag. Non-iterable objects are silently ignored.
  • Looping over dictionaries (or any Mapping) iterates key/value pairs.

Undefined variables

When a template variable or property can't be resolved, an instance of the undefined type is used instead. That is, an instance of micro_liquid.Undefined or a subclass of it.

The default undefined type renders nothing when output, evaluates to False when tested for truthiness and is an empty iterable when looped over. You can pass an alternative undefined type as the undefined keyword argument to the Template constructor to change this behavior.

from micro_liquid import StrictUndefined
from micro_liquid import Template

t = Template("{{ foo.nosuchthing }}", undefined=StrictUndefined)

print(t.render({"foo": {}}))
# micro_liquid.UndefinedVariableError: 'foo.nosuchthing' is undefined
#   -> '{{ foo.nosuchthing }}':1:3
#   |
# 1 | {{ foo.nosuchthing }}
#   |    ^^^ 'foo.nosuchthing' is undefined

Or implement your own.

from typing import Iterator
from micro_liquid import Template
from micro_liquid import Undefined


class MyUndefined(Undefined):
    def __str__(self) -> str:
        return "<MISSING>"

    def __bool__(self) -> bool:
        return False

    def __iter__(self) -> Iterator[object]:
        yield from ()


t = Template("{{ foo.nosuchthing }}", undefined=MyUndefined)

print(t.render({"foo": {}}))  # <MISSING>

Serializing objects

By default, when outputting an object with {{ and }}, lists, dictionaries and tuples are rendered in JSON format. For all other objects we render the result of str(obj).

You can change this behavior by passing a callable to the Template constructor or render function as the serializer keyword argument. The callable should accept an object and return its string representation suitable for output.

This example shows how one might define a serializer that can dump data classes with json.dumps.

import json
from dataclasses import asdict
from dataclasses import dataclass
from dataclasses import is_dataclass

from micro_liquid import Template


@dataclass
class SomeData:
    foo: str
    bar: int


def json_default(obj: object) -> object:
    if is_dataclass(obj) and not isinstance(obj, type):
        return asdict(obj)
    raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable")


def my_serializer(obj: object) -> str:
    return (
        json.dumps(obj, default=json_default)
        if isinstance(obj, (list, dict, tuple))
        else str(obj)
    )


template = Template("{{ some_object }}", serializer=my_serializer)
data = {"some_object": [SomeData("hello", 42)]}

print(template.render(data))  # [{"foo": "hello", "bar": 42}]

TODO: Walk syntax tree

License

micro-liquid is distributed under the terms of the MIT license.

Metadata

Release files for micro-liquid 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for micro-liquid 0.1.0
File Size Uploaded Provenance Actions
micro_liquid-0.1.0.tar.gz 15.5 kB Without provenance Details for micro_liquid-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for micro-liquid 0.1.0
File Interpreter ABI Platform Actions
micro_liquid-0.1.0-py3-none-any.whl Python 3 none any Details for micro_liquid-0.1.0-py3-none-any.whl

Total release size: 40.7 kB

Release files / micro_liquid-0.1.0.tar.gz

Download URL micro_liquid-0.1.0.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
1ccb6f738231f237ab7e2d32f7e642df81bcc4ea786d24976a62e31165ba5d0b
BLAKE2b-256 checksum
How to use checksums
f435398c85906f5551d05ba136a87c4ee2cd492695f13b9d51902c1bda484101
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.10

Release files / micro_liquid-0.1.0-py3-none-any.whl

Download URL micro_liquid-0.1.0-py3-none-any.whl
Size 25.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aaf4ae7e31d0eff99279ed06de26b85b459e71997c1e1a822f95d1839d098788
BLAKE2b-256 checksum
How to use checksums
4ff06e3754cbdebce5552411b98dc12d765a3253239ffff785e1f6452648a74c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.11.10

Security for micro-liquid 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page