Skip to content

Feature Request: Support for Template Inheritance / Layout Extension (Jinja/Django extends style) #45

Description

@glanzel

Is your feature request related to a problem? Please describe.

When coming from traditional template engines like Jinja2 or Django Templates, developers are used to a top-down template inheritance layout pattern via {% extends "base.html" %}.
Currently, in PyJSX, layouts are achieved through a component-wrapper approach (passing elements as children or named properties). While functional, passing multiple layout blocks (e.g., both a specific section and a content block) requires passing fragments as arguments or declaring variables inline. This can feel a bit more verbose than traditional template inheritance.

Describe the solution you'd like

It would be fantastic if PyJSX could support a clean, Pythonic way to handle template inheritance—ideally using a decorator-based approach (@extends) or specific tags that map components together at runtime.
Here is a conceptual idea of how a future version of PyJSX could implement this (Approach A):

# coding: jsx
from pyjsx import jsx, extends

# 1. Define a Base Layout with placeholder blocks
def BaseLayout(blocks):
    return (
        <html lang="en">
        <head>
            <title>My App</title>
            {blocks.get("head")}
        </head>
        <body>
            <main>
                {blocks.get("content")}
            </main>
        </body>
        </html>
    )

# 2. Extend the layout via a Python decorator
@extends(BaseLayout)
def DetailPage():
    return (
        <>
            <block name="head">
                <meta name="description" content="Detail Page" />
                <script src="/static/charts.js"></script>
            </block>

            <block name="content">
                <h1>Details</h1>
                <p>This is the page content.</p>
            </block>
        </>
    )

For reference, to achieve a similar flexible layout with the current version of PyJSX, we have to pass JSX fragments explicitly as properties into the component:

# coding: jsx
from pyjsx import jsx

# Current Layout Component
def CustomLayout(children, extra_head=None):
    return (
        <html>
        <head>
            <title>Flexible Layout</title>
            {extra_head}
        </head>
        <body>
            {children}
        </body>
        </html>
    )

# Current Page Component
def DetailPage():
    return (
        <CustomLayout 
            extra_head={
                <>
                    <meta name="description" content="Detailseite" />
                    <script src="/static/charts.js"></script>
                </>
            }
        >
            <h1>Details</h1>
        </CustomLayout>
    )

Additional context

Implementing a template inheritance pattern would lower the friction for developers migrating from Django/FastAPI+Jinja to a pure PyJSX backend, combining the power of Pythonic JSX with the familiar layouts of classic web frameworks.
Thank you for this awesome library!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions