Module

core.registry

Content Registry - O(1) content lookups by path and URL.

Provides ContentRegistry for centralized page/section lookups with path and URL indexing. Enables efficient access to content during rendering without scanning hierarchies.

Public API:

ContentRegistry: Central registry for page and section lookups

Key Concepts:

Path-Based Lookups: O(1) access by source file path (primary key) URL-Based Lookups: O(1) access by output URL (for virtual content and links) Freeze/Unfreeze: Registry frozen after discovery for thread-safe reads

Lifecycle:

  1. Created empty at Site initialization
  2. Populated during discovery phase (register_page/register_section)
  3. Frozen before rendering phase (freeze())
  4. Cleared on rebuild (clear())

Thread Safety:

  • Writes (register_*) must happen single-threaded during discovery
  • Reads (get_*) are safe after freeze() for concurrent rendering
  • Frozen registry raises BengalError on mutation attempts

Related Packages:

bengal.core.site.core: Site dataclass using this registry bengal.core.url_ownership: URL ownership tracking (composed by registry) bengal.core.site.section_registry: Legacy mixin (delegates to registry)

Classes

ContentRegistry 26
O(1) content lookups by path, URL, and metadata. Thread-safe for reads after freeze(). Rebuilt ato…

O(1) content lookups by path, URL, and metadata.

Thread-safe for reads after freeze(). Rebuilt atomically during discovery.

Lifecycle:

  1. Created empty at Site initialization
    1. Populated during discovery phase (register_page/register_section)

    2. Frozen before rendering phase (freeze())

    3. Cleared on rebuild (clear())

      Thread Safety:

  • Writes (register_*) must happen single-threaded during discovery
  • Reads (get_*) are safe after freeze() for concurrent rendering
  • Frozen registry raises BengalError on mutation attempts

Attributes

Name Type Description
_pages_by_path dict[Path, Page]
_sections_by_path dict[Path, Section]
_pages_by_url dict[str, Page]
_sections_by_url dict[str, Section]
url_ownership URLRegistry

URLRegistry for collision detection and ownership tracking

_root_path Path | None
_frozen bool
_epoch int

Methods

page_count 0 int
Number of registered pages.
property
def page_count(self) -> int
Returns
int
section_count 0 int
Number of registered sections.
property
def section_count(self) -> int
Returns
int
is_frozen 0 bool
Whether the registry is frozen.
property
def is_frozen(self) -> bool
Returns
bool
epoch 0 int
Registry epoch counter for cache invalidation. Incremented when clear() is cal…
property
def epoch(self) -> int

Registry epoch counter for cache invalidation.

Incremented when clear() is called. Used by Page._section to detect when cached section lookups are stale.

Returns
int
get_page 1 Page | None
Get page by source path. O(1) lookup.
def get_page(self, path: Path) -> Page | None
Parameters
Name Type Description
path

Source file path (absolute or relative to content/)

Returns
Page | None Page if found, None otherwise
get_page_by_url 1 Page | None
Get page by output URL. O(1) lookup.
def get_page_by_url(self, url: str) -> Page | None
Parameters
Name Type Description
url

Output URL (e.g., "/about/", "/blog/my-post/")

Returns
Page | None Page if found, None otherwise
get_section 1 Section | None
Get section by directory path. O(1) lookup.
def get_section(self, path: Path) -> Section | None
Parameters
Name Type Description
path

Section directory path (absolute or relative to content/)

Returns
Section | None Section if found, None otherwise
get_section_by_url 1 Section | None
Get section by URL (for virtual sections). O(1) lookup.
def get_section_by_url(self, url: str) -> Section | None
Parameters
Name Type Description
url

Section URL (e.g., "/api/", "/api/core/")

Returns
Section | None Section if found, None otherwise
register_page 1
Register a page. Raises if frozen.
def register_page(self, page: Page) -> None
Parameters
Name Type Description
page

Page to register (must have source_path set)

register_section 1
Register a section. Raises if frozen.
def register_section(self, section: Section) -> None
Parameters
Name Type Description
section

Section to register

register_sections_recursive 1
Register a section and all its subsections recursively.
def register_sections_recursive(self, section: Section) -> None
Parameters
Name Type Description
section

Root section to register (along with all subsections)

freeze 0
Freeze registry after discovery. Enables concurrent reads. Called at the end o…
def freeze(self) -> None

Freeze registry after discovery. Enables concurrent reads.

Called at the end of discovery phase, before rendering begins. After freezing, any mutation attempt raises BengalError.

unfreeze 0
Unfreeze registry for dev server rebuilds. Called at start of reset_ephemeral_…
def unfreeze(self) -> None

Unfreeze registry for dev server rebuilds.

Called at start of reset_ephemeral_state() to allow re-population.

clear 0
Clear all entries for rebuild. Also unfreezes. Called by Site.reset_ephemeral_…
def clear(self) -> None

Clear all entries for rebuild. Also unfreezes.

Called by Site.reset_ephemeral_state() before re-discovery. Increments epoch to invalidate page section caches.

set_root_path 1
Set root path for path normalization.
def set_root_path(self, root_path: Path) -> None
Parameters
Name Type Description
root_path

Site root directory

increment_epoch 0
Increment the epoch counter. Called after sections are re-registered to invali…
def increment_epoch(self) -> None

Increment the epoch counter.

Called after sections are re-registered to invalidate page caches.

Internal Methods 2
_normalize_path 1 Path
Normalize a path for registry lookups. **Normalization ensures consistent look…
def _normalize_path(self, path: Path) -> Path

Normalize a path for registry lookups.

Normalization ensures consistent lookups across platforms:

  • Resolves symlinks to canonical paths
  • Makes path relative to content/ directory
  • Lowercases on case-insensitive filesystems (macOS, Windows)
Parameters
Name Type Description
path

Absolute or relative path

Returns
Path Normalized path suitable for registry keys
__repr__ 0 str
def __repr__(self) -> str
Returns
str