Route Directory Golden Path

The recommended way to structure Chirp route directories for app-shell applications

1 min read 296 words

A section-member page route with minimal boilerplate:

_meta.py — declarative metadata:

from chirp.pages.types import RouteMeta
META = RouteMeta(title="Skills", section="discover", breadcrumb_label="Skills", shell_mode="tabbed")

page.py — domain data only:

from chirp import Page
def get():
    return Page("page.html", "content", items=load_items())

page.html — standard blocks:

{% block page_root %}
{% block page_root_inner %}
{% block page_content %}
  {{ items }}
{% end %}
{% end %}
{% end %}

No _context.pyneeded when the section provides tabs and breadcrumbs.

Register sections inapp.py before mount_pages():

from chirp.pages.types import Section, TabItem

app.register_section(Section(
    id="discover",
    label="Discover",
    tab_items=(
        TabItem(label="Skills", href="/skills"),
        TabItem(label="Chains", href="/chains"),
    ),
    breadcrumb_prefix=({"label": "App", "href": "/"},),
))
app.mount_pages("pages")

For{param}/directories:

_meta.py — dynamic title:

def meta(name: str) -> RouteMeta:
    return RouteMeta(title=f"Skill: {name}", breadcrumb_label=name)

_context.py — load entity, raise if missing:

from chirp import NotFound
def context(name: str) -> dict:
    skill = store.get(name)
    if not skill:
        raise NotFound()
    return {"skill": skill}

page.py — receives loaded entity from cascade:

def get(skill):
    return Page("page.html", "content", skill=skill)

_actions.py@actiondecorated handlers:

from chirp.pages.actions import action

@action("save")
def save(skill_id: str, data: dict):
    update_skill(skill_id, data)
    return {"msg": "saved"}

Templates use _actionform field to dispatch.

Fragment blocks inpage.html, OOB regions in layout. Use shell_actions in _context.pyor handler return for shell updates.

When to Use Each File

Need File
Route metadata (title, section) _meta.py
Inherited context _context.py
POST handlers _actions.py
Complex view assembly _viewmodel.py
Layout wrapper _layout.html
Everything else page.py + page.html