Skip to main content

wagtail-block-reference

BlockReference support for Wagtail - enables forward and cyclic block references.

Heads up: this package works by patching Wagtail internals (Python and JS) to support forward and cyclic block references, which Wagtail doesn't do out of the box. It exists because the upstream PR (wagtail#14279) may take a while to land (if it ever does), and waiting wasn't an option for me :). Relying on internals means relying on internals - so the test suite deliberately targets the patched code paths, and a future Wagtail upgrade that breaks something will fail loudly rather than silently misbehave.

Installation

pip install wagtail-block-reference

Add to INSTALLED_APPS:

INSTALLED_APPS = [
    ...
    "wagtail_block_reference",
]

Usage

from wagtail import blocks
from wagtail_block_reference import BlockReference

class CommentBlock(blocks.StructBlock):
    text = blocks.CharBlock()
    replies = blocks.ListBlock(BlockReference(lambda: CommentBlock))

Targets must resolve to the same instance

A cycle ends when a walk meets a target it has already seen, and "already seen" means the same object. So a reference must resolve to the same block instance every time.

Declaring the target as a class, a dotted path, or a class attribute gives you that for free. A factory does not:

# Fine: one CommentBlock instance, memoised on the reference.
replies = blocks.ListBlock(BlockReference(lambda: CommentBlock))

# Broken: a new block on every resolution, so the graph never closes.
replies = blocks.ListBlock(BlockReference(lambda: registry.build("comment")))

The second form is an infinitely deep graph rather than a cyclic one, and no visited-set can bound it. It shows up most easily with a dynamic block registry - memoise the registry so a given name always yields the same instance.

This is caught rather than left to exhaust the stack: past WAGTAIL_BLOCK_REFERENCE_MAX_WALK_DEPTH levels (default 100), check() reports wagtailcore.E010 and other walks raise BlockReferenceDepthExceeded. Raise the setting if a graph really is nested that deeply through references.

How it works

BlockReference is a lazy proxy that resolves its target block on first access. The target can be a lambda (for forward/cyclic references), a dotted import path, or a block class.

The package ships two patches:

Python patch (patches.py, applied at import time): hooks into Wagtail's block metaclass so that BlockReference attributes declared on a StructBlock are collected as child blocks, and registers a telepath adapter so the block serialises as its resolved target. Patches are applied with wrapt rather than plain attribute assignment - it wraps the live descriptor (including the metaclass's implicit-staticmethod __new__) and hands each wrapper the current original via wrapped, which is more reliable than reassigning SomeClass.method = ... outright.

JS patch (patch.js, injected via insert_global_admin_js): waits for Wagtail to set window.telepath, then replaces it outright with a vendored Telepath implementation (wagtail/telepath-unpack#5) that has cyclic/back-reference (_ref) support built into unpack itself, carrying over any constructors already registered on the instance it replaces. It also wraps StructBlock and StreamBlock prototypes with a lazy childBlockDefsByName getter - without that, the cyclic telepath graph causes a Maximum call stack size exceeded crash when the editor tries to build the block name map at construction time.

Supported versions

All Wagtail versions that are currently under active or security support: 7.0 LTS, 7.3, and 7.4 LTS. CI tests against each of these. Versions drop off the matrix as they go end-of-life.

CI also runs a non-blocking preview job against the latest Wagtail 8.0 pre-release (currently 8.0rc1), so breakage surfaces before the actual release rather than after.

Development

# Install dependencies
uv sync

# Lint, format & type-check
uv run ruff check .
uv run ruff format .
uv run ty check

# Run all tests (unit + E2E) against a single Wagtail version
uv run playwright install chromium
uv run pytest tests/

# Run all tests against all supported Wagtail versions (installs Chromium automatically)
uv run tox

# Run all tests against all supported Wagtail versions (installs Chromium automatically)
# and see visually what the browser is doing
uv run tox  -- --headed --slowmo=500

# Run against a specific version
uv run tox -e wagtail74

# Run against a specific version and see visually what the browser is doing
uv run tox -e wagtail74 -- --headed --slowmo=500

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wagtail_block_reference-0.3.2.tar.gz (71.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wagtail_block_reference-0.3.2-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file wagtail_block_reference-0.3.2.tar.gz.

File metadata

  • Download URL: wagtail_block_reference-0.3.2.tar.gz
  • Upload date:
  • Size: 71.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wagtail_block_reference-0.3.2.tar.gz
Algorithm Hash digest
SHA256 45c0c1351e8da8e648d911278c029b00cce6c6dc130942d01cda98c0f7086ab2
MD5 409f7bfc73207b0ec017b7b422ab6fcf
BLAKE2b-256 2243435c5ed5ff2ad6808e4eec32fc3c592cd52adab513ecddb8a0f151a80417

See more details on using hashes here.

Provenance

The following attestation bundles were made for wagtail_block_reference-0.3.2.tar.gz:

Publisher: publish.yml on joeyjurjens/wagtail-block-reference

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wagtail_block_reference-0.3.2-py3-none-any.whl.

File metadata

File hashes

Hashes for wagtail_block_reference-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 904124a0adcab81eea660c564391fba25c06d6b1640ca1b17f4661aef7b97252
MD5 9e0df08e23c18b1e4768a93696d81934
BLAKE2b-256 dccf2dd4574d8a186f81dcadbef4c446e2097e78afdd6f8b4418d51069d8dea4

See more details on using hashes here.

Provenance

The following attestation bundles were made for wagtail_block_reference-0.3.2-py3-none-any.whl:

Publisher: publish.yml on joeyjurjens/wagtail-block-reference

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

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