Page-template-extends-registered-layout footgun detection.
When a page-leaf template uses{% extends "_layout.html" %}and
_layout.htmlis registered as a layout in this page's chain, two things
break silently:
-
Block overrides are dropped.
render_with_blocksonly injects the page's rendered HTML into the layout'scontentslot — sibling block overrides like{% block page_scripts %}defined on the page never reach the layout. The page author wonders why their inline script tag doesn't show up; nothing in the console explains it. -
The layout structure renders twice. kida's extends inheritance fills the layout structure during page render, then
render_with_layoutswraps that already-wrapped HTML in the same layout chain again — the<html>/<body>shell appears nested inside itself.
check_unreachable_blockscovers the no-extends sibling-block case but
explicitly skips templates that use{% extends %}(see
rules_unreachable_blocks.py); this rule is the complementary check
targeting the extends-into-a-registered-layout case.
Detection is conservative: only fires when the extended target is in this
app's set of registered layout template names. Pages that extend a
non-layout kida partial (e.g. the_page_layout.htmlpattern in
examples/standalone/oob_layout_chain/) are intentionally allowed.
contracts.rules_composition
| Name | Type | Default | Description |
|---|---|---|---|
type
|
|
— | |
qualified_name
|
|
— | |
element_type
|
|
— | |
description
|
|
— | |
source_file
|
|
— | |
line_number
|
|
— | |
is_autodoc
|
|
— | |
autodoc_element
|
|
— | |
_autodoc_template
|
|
— | |
_autodoc_url_path
|
|
— | |
_autodoc_page_type
|
|
— | |
title
|
|
— | |
doc_content_hash
|
|
— |
Symbols on this page
_registered_layout_names
function
def _registered_layout_names(layout_chains: list[Any]) -> set[str]
Collect every layout template name registered in any page chain.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
layout_chains
|
list[Any]
|
— |
check_page_extends_layout
function
def check_page_extends_layout(page_leaf_templates: set[str], layout_chains: list[Any], kida_env: Environment | None) -> list[ContractIssue]
Flag page-leaf templates that{% extends %}a registered layout.
Composition (render_with_blocks) and inheritance ({% extends %})
are not interchangeable in Chirp's page convention. When both are in
play against the same template, block overrides drop silently and the
layout structure renders twice.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
page_leaf_templates
|
set[str]
|
— | |
layout_chains
|
list[Any]
|
— | |
kida_env
|
Environment | None
|
— |
View source · /home/runner/work/chirp/chirp/site/../src/chirp/contracts/rules_composition.py:1