Module

core.page.proxy

PageProxy - Lazy-loaded page placeholder for incremental builds.

A PageProxy holds minimal page metadata (title, date, tags, etc.) loaded from the PageDiscoveryCache and defers loading full page content until needed.

This enables incremental builds to skip disk I/O and parsing for unchanged pages while maintaining transparent access (code doesn't know it's lazy).

Architecture:

  • Metadata loaded immediately from cache (fast)
  • Full content loaded on first access to .content or other lazy properties
  • Transparent to callers - behaves like a normal Page object
  • Falls back to eager load if cascades or complex operations detected

Classes

PageProxy
Lazy-loaded page placeholder. Holds page metadata from cache and defers loading full content until…
68

Lazy-loaded page placeholder.

Holds page metadata from cache and defers loading full content until accessed. Transparent to callers - implements Page-like interface.

LIFECYCLE IN INCREMENTAL BUILDS:


  1. Discovery (content_discovery.py):

    • Created from cached metadata for unchanged pages
    • Has: title, date, tags, slug, _section, _site, output_path
    • Does NOT have: content, rendered_html (lazy-loaded on demand)
  2. Filtering (incremental.py):

    • PageProxy objects pass through find_work_early() unchanged
    • Only modified pages become full Page objects for rendering
  3. Rendering (render.py):

    • Modified pages rendered as full Page objects
    • PageProxy objects skipped (already have cached output)
  4. Update (build/rendering.py Phase 15):

    • Freshly rendered Page objects REPLACE their PageProxy counterparts
    • site.pages becomes: mix of fresh Page (rebuilt) + PageProxy (cached)
  5. Postprocessing (postprocess.py):

    • Iterates over site.pages (now updated with fresh Pages)
    • ⚠️ CRITICAL: PageProxy must implement ALL properties/methods used:
      • output_path (for finding where to write .txt/.json)
      • url, permalink (for generating index.json)
      • title, date, tags (for content in output files)

TRANSPARENCY CONTRACT:


PageProxy must be transparent to:

  • Templates: Implements .url, .permalink, .title, etc.
  • Postprocessing: Implements .output_path, metadata access
  • Navigation: Implements .prev, .next (via lazy load)

⚠️ When adding new Page properties used by templates/postprocessing, MUST also add to PageProxy or handle in _ensure_loaded().

Usage:

# Create from cached metadata
page = PageProxy(
    source_path=Path("content/post.md"),
    metadata=cached_metadata,
    loader=load_page_from_disk,  # Callable that loads full page
)

# Access metadata (instant, from cache)
print(page.title)  # "My Post"
print(page.tags)   # ["python", "web"]

# Access full content (triggers lazy load)
print(page.content)  # Loads from disk and parses

# After first access, it's fully loaded
assert page._lazy_loaded  # True

Attributes

Name Type Description
_site Site | None

Methods 59

title property
Get page title from cached metadata.
str
def title(self) -> str

Get page title from cached metadata.

Returns

str

date property
Get page date from cached metadata (parsed from ISO string).
datetime | None
def date(self) -> datetime | None

Get page date from cached metadata (parsed from ISO string).

Returns

datetime | None

tags property
Get page tags from cached metadata.
list[str]
def tags(self) -> list[str]

Get page tags from cached metadata.

Returns

list[str]

slug property
Get URL slug from cached metadata.
str | None
def slug(self) -> str | None

Get URL slug from cached metadata.

Returns

str | None

weight property
Get sort weight from cached metadata.
int | None
def weight(self) -> int | None

Get sort weight from cached metadata.

Returns

int | None

lang property
Get language code from cached metadata.
str | None
def lang(self) -> str | None

Get language code from cached metadata.

Returns

str | None

type property
Get page type from cached metadata (cascaded).
str | None
def type(self) -> str | None

Get page type from cached metadata (cascaded).

Returns

str | None

variant property
Get visual variant from cached metadata (Mode). Falls back to legacy layout/he…
str | None
def variant(self) -> str | None

Get visual variant from cached metadata (Mode).

Falls back to legacy layout/hero_style fields in props if not set.

Returns

str | None

props property
Get custom props from cached metadata. This provides access to the 'props' dic…
dict[str, Any]
def props(self) -> dict[str, Any]

Get custom props from cached metadata.

This provides access to the 'props' dictionary (formerly metadata) without loading the full page.

Returns

dict[str, Any]

section property
Get section path from cached metadata.
str | None
def section(self) -> str | None

Get section path from cached metadata.

Returns

str | None

relative_path property
Get relative path string (alias for source_path as string).
str
def relative_path(self) -> str

Get relative path string (alias for source_path as string).

Returns

str

aliases property
Get redirect aliases from cached metadata.
list[str]
def aliases(self) -> list[str]

Get redirect aliases from cached metadata.

Returns

list[str]

content property
Get page content (lazy-loaded from disk).
str
def content(self) -> str

Get page content (lazy-loaded from disk).

Returns

str

metadata property
Get metadata dict from cache (no lazy load). Returns cached metadata including…
dict[str, Any]
def metadata(self) -> dict[str, Any]

Get metadata dict from cache (no lazy load).

Returns cached metadata including cascaded fields like 'type'. This allows templates to check page.metadata.get("type") without triggering a full page load.

Returns

dict[str, Any]

rendered_html property
Get rendered HTML (lazy-loaded).
str
def rendered_html(self) -> str

Get rendered HTML (lazy-loaded).

Returns

str

links property
Get extracted links (lazy-loaded).
list[str]
def links(self) -> list[str]

Get extracted links (lazy-loaded).

Returns

list[str]

version property
Get version (lazy-loaded).
str | None
def version(self) -> str | None

Get version (lazy-loaded).

Returns

str | None

toc property
Get table of contents (lazy-loaded).
str | None
def toc(self) -> str | None

Get table of contents (lazy-loaded).

Returns

str | None

toc_items property
Get TOC items (lazy-loaded).
list[dict[str, Any]]
def toc_items(self) -> list[dict[str, Any]]

Get TOC items (lazy-loaded).

Returns

list[dict[str, Any]]

output_path property
Get output path (lazy-loaded).
Path | None
def output_path(self) -> Path | None

Get output path (lazy-loaded).

Returns

Path | None

parsed_ast property
Get parsed AST (lazy-loaded).
Any
def parsed_ast(self) -> Any

Get parsed AST (lazy-loaded).

Returns

Any

related_posts property
Get related posts (lazy-loaded).
list[Page]
def related_posts(self) -> list[Page]

Get related posts (lazy-loaded).

Returns

list[Page]

translation_key property
Get translation key.
str | None
def translation_key(self) -> str | None

Get translation key.

Returns

str | None

url property
Get the URL path for the page (lazy-loaded, cached after first access).
str
def url(self) -> str

Get the URL path for the page (lazy-loaded, cached after first access).

Returns

str

relative_url property
Get the relative URL (without baseurl) for the page (lazy-loaded, cached after …
str
def relative_url(self) -> str

Get the relative URL (without baseurl) for the page (lazy-loaded, cached after first access).

Returns

str

permalink property
Get the permalink (URL with baseurl) for the page (lazy-loaded, cached after fi…
str
def permalink(self) -> str

Get the permalink (URL with baseurl) for the page (lazy-loaded, cached after first access).

Returns

str

meta_description property
Get meta description (lazy-loaded from full page).
str
def meta_description(self) -> str

Get meta description (lazy-loaded from full page).

Returns

str

reading_time property
Get reading time estimate (lazy-loaded from full page).
str
def reading_time(self) -> str

Get reading time estimate (lazy-loaded from full page).

Returns

str

excerpt property
Get content excerpt (lazy-loaded from full page).
str
def excerpt(self) -> str

Get content excerpt (lazy-loaded from full page).

Returns

str

keywords property
Get keywords (lazy-loaded from full page).
list[str]
def keywords(self) -> list[str]

Get keywords (lazy-loaded from full page).

Returns

list[str]

parent property
Get the parent section of this page. Returns parent section without forcing fu…
Any
def parent(self) -> Any

Get the parent section of this page.

Returns parent section without forcing full page load (uses _section).

Returns

Any

ancestors property
Get all ancestor sections of this page. Returns list of ancestor sections from…
list[Any]
def ancestors(self) -> list[Any]

Get all ancestor sections of this page.

Returns list of ancestor sections from immediate parent to root without forcing full page load (uses _section property).

Returns

list[Any]

is_home property
Check if this page is the home page.
bool
def is_home(self) -> bool

Check if this page is the home page.

Returns

bool

is_section property
Check if this page is a section page.
bool
def is_section(self) -> bool

Check if this page is a section page.

Returns

bool

is_page property
Check if this is a regular page (not a section).
bool
def is_page(self) -> bool

Check if this is a regular page (not a section).

Returns

bool

kind property
Get the kind of page: 'home', 'section', or 'page'.
str
def kind(self) -> str

Get the kind of page: 'home', 'section', or 'page'.

Returns

str

description property
Get page description. Favors core.description (fast, cached) but falls back to…
str
def description(self) -> str

Get page description.

Favors core.description (fast, cached) but falls back to full page load if not available, for backward compatibility.

Returns

str

draft property
Check if page is marked as draft.
bool
def draft(self) -> bool

Check if page is marked as draft.

Returns

bool

hidden property
Check if page is hidden (unlisted).
bool
def hidden(self) -> bool

Check if page is hidden (unlisted).

Returns

bool

visibility property
Get visibility settings with defaults.
dict[str, Any]
def visibility(self) -> dict[str, Any]

Get visibility settings with defaults.

Returns

dict[str, Any]

in_listings property
Check if page should appear in listings/queries.
bool
def in_listings(self) -> bool

Check if page should appear in listings/queries.

Returns

bool

in_sitemap property
Check if page should appear in sitemap.
bool
def in_sitemap(self) -> bool

Check if page should appear in sitemap.

Returns

bool

in_search property
Check if page should appear in search index.
bool
def in_search(self) -> bool

Check if page should appear in search index.

Returns

bool

in_rss property
Check if page should appear in RSS feeds.
bool
def in_rss(self) -> bool

Check if page should appear in RSS feeds.

Returns

bool

robots_meta property
Get robots meta content for this page.
str
def robots_meta(self) -> str

Get robots meta content for this page.

Returns

str

should_render property
Check if page should be rendered.
bool
def should_render(self) -> bool

Check if page should be rendered.

Returns

bool

next property
Get next page in site collection.
Page | None
def next(self) -> Page | None

Get next page in site collection.

Returns

Page | None

prev property
Get previous page in site collection.
Page | None
def prev(self) -> Page | None

Get previous page in site collection.

Returns

Page | None

next_in_section property
Get next page in same section.
Page | None
def next_in_section(self) -> Page | None

Get next page in same section.

Returns

Page | None

prev_in_section property
Get previous page in same section.
Page | None
def prev_in_section(self) -> Page | None

Get previous page in same section.

Returns

Page | None

rendered_html
Set rendered HTML.
1 None
def rendered_html(self, value: str) -> None

Set rendered HTML.

Parameters 1
value str
toc
Set table of contents.
1 None
def toc(self, value: str | None) -> None

Set table of contents.

Parameters 1
value str | None
output_path
Set output path.
1 None
def output_path(self, value: Path | None) -> None

Set output path.

Parameters 1
value Path | None
parsed_ast
Set parsed AST.
1 None
def parsed_ast(self, value: Any) -> None

Set parsed AST.

Parameters 1
value Any
related_posts
Set related posts. In incremental mode, allow setting on proxy without forcing…
1 None
def related_posts(self, value: list[Page]) -> None

Set related posts.

In incremental mode, allow setting on proxy without forcing a full load.

Parameters 1
value list[Page]
should_render_in_environment
Check if page should be rendered in the given environment.
1 bool
def should_render_in_environment(self, is_production: bool = False) -> bool

Check if page should be rendered in the given environment.

Parameters 1
is_production bool
Returns

bool

extract_links
Extract links from content.
0 None
def extract_links(self) -> None

Extract links from content.

get_load_status
Get debugging info about proxy state.
0 dict[str, Any]
def get_load_status(self) -> dict[str, Any]

Get debugging info about proxy state.

Returns

dict[str, Any]

from_page classmethod
Create proxy from full page (for testing).
2 PageProxy
def from_page(cls, page: Page, metadata: Any) -> PageProxy

Create proxy from full page (for testing).

Parameters 2
page Page
metadata Any
Returns

PageProxy

Internal Methods 9
_section property
Get the section this page belongs to (lazy lookup via path). If the page is lo…
Any | None
def _section(self) -> Any | None

Get the section this page belongs to (lazy lookup via path).

If the page is loaded, delegates to the full page's _section property. Otherwise, performs path-based lookup via site registry without forcing load.

Returns

Any | None

Section object if found, None otherwise

__init__
Initialize PageProxy with PageCore metadata and loader.
3 None
def __init__(self, source_path: Path, metadata: PageCore, loader: Callable[[Path], Page])

Initialize PageProxy with PageCore metadata and loader.

Parameters 3
source_path Path

Path to source content file

metadata PageCore

PageCore with cached page metadata (title, date, tags, etc.)

loader Callable[[Path], Page]

Callable that loads full Page(source_path) -> Page

_parse_date
Parse ISO date string to datetime (deprecated, use date property).
1 datetime | None
def _parse_date(self, date_str: str) -> datetime | None

Parse ISO date string to datetime (deprecated, use date property).

Parameters 1
date_str str
Returns

datetime | None

_ensure_loaded
Load full page content if not already loaded.
0 None
def _ensure_loaded(self) -> None

Load full page content if not already loaded.

_section
Set the section this page belongs to (stores path, not object).
1 None
def _section(self, value: Any) -> None

Set the section this page belongs to (stores path, not object).

Parameters 1
value Any

Section object or None

__hash__
Hash based on source_path (same as Page).
0 int
def __hash__(self) -> int

Hash based on source_path (same as Page).

Returns

int

__eq__
Equality based on source_path.
1 bool
def __eq__(self, other: Any) -> bool

Equality based on source_path.

Parameters 1
other Any
Returns

bool

__repr__
String representation.
0 str
def __repr__(self) -> str

String representation.

Returns

str

__str__
String conversion.
0 str
def __str__(self) -> str

String conversion.

Returns

str