# page URL: /api/core/page/ Section: page -------------------------------------------------------------------------------- page - Bengal window.BENGAL_THEME_DEFAULTS = { appearance: 'dark', palette: 'snow-lynx' }; // Progressive Enhancement System Configuration window.Bengal = window.Bengal || {}; window.Bengal.enhanceBaseUrl = '/bengal/assets/js/enhancements'; window.Bengal.watchDom = true; window.Bengal.debug = false; (function () { try { var defaults = window.BENGAL_THEME_DEFAULTS || { appearance: 'system', palette: '' }; var defaultAppearance = defaults.appearance; if (defaultAppearance === 'system') { defaultAppearance = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } var storedTheme = localStorage.getItem('bengal-theme'); var storedPalette = localStorage.getItem('bengal-palette'); var theme = storedTheme ? (storedTheme === 'system' ? defaultAppearance : storedTheme) : defaultAppearance; var palette = storedPalette ?? defaults.palette; document.documentElement.setAttribute('data-theme', theme); if (palette) { document.documentElement.setAttribute('data-palette', palette); } } catch (e) { document.documentElement.setAttribute('data-theme', 'light'); } })(); Skip to main content Magnifying Glass ESC Recent Clear Magnifying Glass No results for "" Try different keywords or check your spelling Start typing to search... ↑↓ Navigate ↵ Open ESC Close Powered by Lunr ᓚᘏᗢ Documentation Info About Arrow Clockwise Get Started Note Tutorials File Text Content Palette Theming Settings Building Starburst Extending Bookmark Reference Learning Tracks Releases Dev GitHub API Reference bengal CLI Magnifying Glass Search ⌘K Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal List ᓚᘏᗢ Magnifying Glass Search X Close Documentation Info About Arrow Clockwise Get Started Note Tutorials File Text Content Palette Theming Settings Building Starburst Extending Bookmark Reference Learning Tracks Releases Dev GitHub API Reference bengal CLI Palette Appearance Chevron Down Mode Monitor System Sun Light Moon Dark Palette Snow Lynx Brown Bengal Silver Bengal Charcoal Bengal Blue Bengal API Reference __main__ bengal Caret Right Folder Analysis community_detection graph_analysis graph_reporting graph_visualizer knowledge_graph link_suggestions link_types page_rank path_analysis performance_advisor results Caret Right Folder Assets manifest pipeline Caret Right Folder Autodoc base config docstring_parser utils virtual_orchestrator Caret Right Folder Extractors cli openapi python Caret Right Folder Models cli common openapi python Caret Right Folder Cache asset_dependency_map cache_store cacheable compression dependency_tracker page_discovery_cache query_index query_index_registry taxonomy_index utils Caret Right Folder Build Cache autodoc_tracking core file_tracking fingerprint parsed_content_cache rendered_output_cache taxonomy_index_mixin validation_cache Caret Right Folder Indexes author_index category_index date_range_index section_index Caret Right Folder Cli __main__ base site_templates utils Caret Right Folder Commands assets build clean collections config debug explain fix health init perf project serve site skeleton sources theme utils validate Caret Right Folder Graph __main__ bridges communities orphans pagerank report suggest Caret Right Folder New config presets scaffolds site wizard Caret Right Folder Helpers cli_app_loader cli_output config_validation error_handling menu_config metadata progress site_loader traceback validation Caret Right Folder Skeleton hydrator schema Caret Right Folder Templates base registry Caret Right Folder Blog template Caret Right Folder Changelog template Caret Right Folder Default template Caret Right Folder Docs template Caret Right Folder Landing template Caret Right Folder Portfolio template Caret Right Folder Resume template Caret Right Folder Collections errors loader schemas validator Caret Right Folder Config defaults deprecation directory_loader env_overrides environment feature_mappings hash loader merge origin_tracker validators Caret Right Folder Content Layer entry loaders manager source Caret Right Folder Sources github local notion rest Caret Right Folder Content Types base registry strategies Caret Right Folder Core build_context cascade_engine menu section theme Caret Right Folder Asset asset_core css_transforms Caret Right Folder Page computed content metadata navigation operations page_core proxy relationships utils Caret Right Folder Site core data discovery factories page_caches properties section_registry theme Caret Right Folder Debug base config_inspector content_migrator delta_analyzer dependency_visualizer explainer incremental_debugger models reporter shortcode_sandbox Caret Right Folder Discovery asset_discovery content_discovery Caret Right Folder Fonts downloader generator Caret Right Folder Health autofix base health_check report Caret Right Folder Linkcheck async_checker ignore_policy internal_checker models orchestrator Caret Right Folder Validators anchors assets cache config connectivity cross_ref fonts links menu navigation output performance rendering rss sitemap taxonomy tracks Caret Right Folder Directives analysis checkers constants Caret Right Folder Orchestration asset content full_to_incremental incremental menu postprocess related_posts render section static streaming taxonomy Caret Right Folder Postprocess html_output redirects rss sitemap special_pages Caret Right Folder Output Formats index_generator json_generator llm_generator lunr_index_generator txt_generator utils Caret Right Folder Rendering api_doc_enhancer asset_extractor errors jinja_utils link_transformer link_validator pygments_cache renderer template_context template_profiler validator Caret Right Folder Parsers base factory mistune native_html pygments_patch python_markdown Caret Right Folder Pipeline core output thread_local toc transforms Caret Right Folder Plugins badges cross_references inline_icon term variable_substitution Caret Right Folder Directives _icons admonitions badge base button cache cards checklist code_tabs container contracts data_table dropdown embed errors example_label fenced figure glossary icon include list_table literalinclude marimo navigation options rubric steps tabs target term terminal tokens utils validator video Caret Right Folder Template Engine asset_url core environment manifest menu url_helpers Caret Right Folder Template Functions advanced_collections advanced_strings autodoc collections content crossref data dates debug files get_page i18n icons images math_functions navigation pagination_helpers seo strings tables taxonomies theme urls Caret Right Folder Server build_handler component_preview constants dev_server live_reload pid_manager reload_controller request_handler request_logger resource_manager utils Caret Right Folder Services validation Caret Right Folder Themes config Caret Right Folder Utils atomic_write autodoc build_context build_stats build_summary cli_output css_minifier dates dotdict error_handlers file_io file_lock hashing incremental_constants js_bundler live_progress logger metadata observability page_initializer pagination path_resolver paths performance_collector performance_report profile progress retry rich_console sections swizzle text theme_registry theme_resolution thread_local traceback_config traceback_renderer url_normalization url_strategy Core ᗢ Caret Down Link Copy URL External Open LLM text Copy Copy LLM text Share with AI Ask Claude Ask ChatGPT Ask Gemini Ask Copilot Module core.page Page representation for content pages in Bengal SSG. This module provides the main Page class, which combines multiple mixins to provide a complete page interface while maintaining separation of concerns. Pages represent markdown content files and provide metadata, navigation, content processing, and template rendering capabilities. Key Concepts: Mixin architecture: Separated concerns via mixins (metadata, content, navigation) Hashability: Pages hashable by source_path for set operations AST-based content: Content represented as AST for efficient processing Cacheable metadata: PageCore provides cacheable page metadata Related Modules: bengal.core.page.page_core: Cacheable page metadata bengal.core.page.proxy: Lazy-loaded page placeholder bengal.rendering.renderer: Page rendering logic bengal.orchestration.content: Content discovery and page creation See Also: bengal/core/page/__init__.py: Page class for page representation plan/active/rfc-content-ast-architecture.md: AST architecture RFC View source 1 Class Classes Page dataclass Represents a single content page. HASHABILITY: ============ Pages are hashable based on their sour… 14 Caret Right Represents a single content page. HASHABILITY: ============ Pages are hashable based on their source_path, allowing them to be stored in sets and used as dictionary keys. This enables: Fast membership tests (O(1) instead of O(n)) Automatic deduplication with sets Set operations for page analysis Direct use as dictionary keys Two pages with the same source_path are considered equal, even if their content differs. The hash is stable throughout the page lifecycle because source_path is immutable. Mutable fields (content, rendered_html, etc.) do not affect the hash or equality. VIRTUAL PAGES: ============== Virtual pages represent dynamically-generated content (e.g., API docs) that doesn't have a corresponding file on disk. Virtual pages: Have _virtual=True and a synthetic source_path Are created via Page.create_virtual() factory Don't read from disk (content provided directly) Integrate with site's page collection and navigation BUILD LIFECYCLE: ================ Pages progress through distinct build phases. Properties have different availability depending on the current phase: Discovery (content_discovery.py) ✅ Available: source_path, content, metadata, title, slug, date ❌ Not available: toc, parsed_ast, toc_items, rendered_html Parsing (pipeline.py) ✅ Available: All Stage 1 + toc, parsed_ast ✅ toc_items can be accessed (will extract from toc) Rendering (pipeline.py) ✅ Available: All previous + rendered_html, output_path ✅ All properties fully populated Note: Some properties like toc_items can be accessed early (returning []) but won't cache empty results, allowing proper extraction after parsing. Inherits from PageMetadataMixin, PageNavigationMixin, PageComputedMixin, PageRelationshipsMixin, PageOperationsMixin, PageContentMixin Attributes Name Type Description _global_missing_section_warnings ClassVar[dict[str, int]] _MAX_WARNING_KEYS ClassVar[int] source_path Path Path to the source content file (synthetic for virtual pages) core PageCore | None content str Raw content (Markdown, etc.) metadata dict[str, Any] Frontmatter metadata (title, date, tags, etc.) parsed_ast Any | None Abstract Syntax Tree from parsed content rendered_html str Rendered HTML output output_path Path | None Path where the rendered page will be written links list[str] List of links found in the page tags list[str] Tags associated with the page version str | None Version information for versioned content toc str | None Table of contents HTML (auto-generated from headings) related_posts list[Page] Related pages (pre-computed during build based on tag overlap) lang str | None translation_key str | None aliases list[str] _site Any | None _section_path Path | None _section_url str | None _toc_items_cache list[dict[str, Any]] | None _ast_cache list[dict[str, Any]] | None _html_cache str | None _plain_text_cache str | None _virtual bool True if this is a virtual page (not backed by a disk file) _prerendered_html str | None _template_name str | None toc_items — Structured TOC data for custom rendering Methods 6 Tag is_virtual property Check if this is a virtual page (not backed by a disk file). Virtual pages are… bool Caret Right def is_virtual(self) -> bool Check if this is a virtual page (not backed by a disk file). Virtual pages are used for: API documentation generated from Python source code Dynamically-generated content from external sources Content that doesn't have a corresponding content/ file Returns bool — True if this page is virtual (not backed by a disk file) Tag template_name property Get custom template name for this page. Virtual pages may specify a custom tem… str | None Caret Right def template_name(self) -> str | None Get custom template name for this page. Virtual pages may specify a custom template for rendering. Returns None to use the default template selection logic. Returns str | None Tag prerendered_html property Get pre-rendered HTML for virtual pages. Virtual pages with pre-rendered HTML … str | None Caret Right def prerendered_html(self) -> str | None Get pre-rendered HTML for virtual pages. Virtual pages with pre-rendered HTML bypass markdown parsing and use this HTML directly in the template. Returns str | None Tag relative_path property Get relative path string (alias for source_path as string). Used by templates … str Caret Right def relative_path(self) -> str Get relative path string (alias for source_path as string). Used by templates and filtering where a string path is expected. This provides backward compatibility and convenience. Returns str normalize_core_paths Normalize PageCore paths to be relative (for cache consistency). This should b… 0 None Caret Right def normalize_core_paths(self) -> None Normalize PageCore paths to be relative (for cache consistency). This should be called before caching to ensure all paths are relative to the site root, preventing absolute path leakage into cache. Note: Directly mutates self.core.source_path since dataclasses are mutable. create_virtual classmethod Create a virtual page for dynamically-generated content. Virtual pages are not… 8 Page Caret Right def create_virtual(cls, source_id: str, title: str, content: str = '', metadata: dict[str, Any] | None = None, rendered_html: str | None = None, template_name: str | None = None, output_path: Path | None = None, section_path: Path | None = None) -> Page Create a virtual page for dynamically-generated content. Virtual pages are not backed by a disk file but integrate with the site's page collection, navigation, and rendering pipeline. Parameters 8 source_id str Unique identifier for this page (used as source_path) title str Page title content str Raw content (markdown) - optional if rendered_html provided metadata dict[str, Any] | None Page metadata/frontmatter rendered_html str | None Pre-rendered HTML (bypasses markdown parsing) template_name str | None Custom template name (optional) output_path Path | None Explicit output path (optional) section_path Path | None Section this page belongs to (optional) Returns Page — A new virtual Page instance Internal Methods 8 Caret Right Tag _section property Get the section this page belongs to (lazy lookup via path or URL). This prope… Any | None Caret Right def _section(self) -> Any | None Get the section this page belongs to (lazy lookup via path or URL). This property performs a path-based or URL-based lookup in the site's section registry, enabling stable section references across rebuilds when Section objects are recreated. Virtual sections (path=None) use URL-based lookups via _section_url. Regular sections use path-based lookups via _section_path. Returns Any | None — Section object if found, None if page has no section or section not found Implementation Note: Uses counter-gated warnings to prevent log spam when sections are missing (warns first 3 times, shows summary, then silent). __post_init__ Initialize computed fields and PageCore. 0 None Caret Right def __post_init__(self) -> None Initialize computed fields and PageCore. _init_core_from_fields Initialize PageCore from Page fields (backward compatibility helper). This all… 0 None Caret Right def _init_core_from_fields(self) -> None Initialize PageCore from Page fields (backward compatibility helper). This allows existing code that creates Page objects without passing core to continue working. Once all instantiation is updated, this can be removed and core made required. Note: Initially creates PageCore with absolute paths, but normalize_core_paths() should be called before caching to convert to relative paths. __hash__ Hash based on source_path for stable identity. The hash is computed from the p… 0 int Caret Right def __hash__(self) -> int Hash based on source_path for stable identity. The hash is computed from the page's source_path, which is immutable throughout the page lifecycle. This allows pages to be stored in sets and used as dictionary keys. Returns int — Integer hash of the source path __eq__ Pages are equal if they have the same source path. Equality is based on source… 1 bool Caret Right def __eq__(self, other: Any) -> bool Pages are equal if they have the same source path. Equality is based on source_path only, not on content or other mutable fields. This means two Page objects representing the same source file are considered equal, even if their processed content differs. Parameters 1 other Any Object to compare with Returns bool — True if other is a Page with the same source_path __repr__ 0 str Caret Right def __repr__(self) -> str Returns str _format_path_for_log Format a path as relative to site root for logging. Makes paths relative to th… 1 str | None Caret Right def _format_path_for_log(self, path: Path | str | None) -> str | None Format a path as relative to site root for logging. Makes paths relative to the site root directory to avoid showing user-specific absolute paths in logs and warnings. Parameters 1 path Path | str | None Path to format (can be Path, str, or None) Returns str | None — Relative path string, or None if path was None _section Set the section this page belongs to (stores path or URL, not object). This se… 1 None Caret Right def _section(self, value: Any) -> None Set the section this page belongs to (stores path or URL, not object). This setter extracts the path (or URL for virtual sections) from the Section object and stores it, enabling stable references when Section objects are recreated during incremental rebuilds. For virtual sections (path=None), stores relative_url in _section_url. For regular sections, stores path in _section_path. Parameters 1 value Any Section object or None ← Previous operations Next → page_core List © 2025 Bengal ᓚᘏᗢ window.BENGAL_LAZY_ASSETS = { tabulator: '/bengal/assets/js/tabulator.min.js', dataTable: '/bengal/assets/js/data-table.js', mermaidToolbar: '/bengal/assets/js/mermaid-toolbar.9de5abba.js', mermaidTheme: '/bengal/assets/js/mermaid-theme.344822c5.js', graphMinimap: '/bengal/assets/js/graph-minimap.cc7e42e3.js', graphContextual: '/bengal/assets/js/graph-contextual.440e59c6.js' }; window.BENGAL_ICONS = { close: '/bengal/assets/icons/close.911d4fe1.svg', enlarge: '/bengal/assets/icons/enlarge.652035e5.svg', copy: '/bengal/assets/icons/copy.3d56e945.svg', 'download-svg': '/bengal/assets/icons/download.04f07e1b.svg', 'download-png': '/bengal/assets/icons/image.c34dfd40.svg', 'zoom-in': '/bengal/assets/icons/zoom-in.237b4a83.svg', 'zoom-out': '/bengal/assets/icons/zoom-out.38857c77.svg', reset: '/bengal/assets/icons/reset.d26dba29.svg' }; Arrow Up X -------------------------------------------------------------------------------- Metadata: - Author: lbliii - Word Count: 2501 - Reading Time: 13 minutes