Skip to main content

UI components for Python using Pydantic and Jinja2 templates

Project description

PyJinHx

Declare reusable, type-safe UI components for template-based web apps in Python. PyJinHx combines Pydantic models with Jinja2 templates to give you automatic template discovery, nested composition, and JavaScript integration—all without manual wiring.

Installation

pip install pyjinhx

Core Capabilities

Automatic Template Discovery

  • Define a component class and place an HTML template in the same directory with a matching name
  • PyJinHx automatically finds components/ui/button.html for a Button class in components/ui/button.py
  • No manual template path configuration needed

Global Component Registry

  • Every component automatically registers itself by its id when instantiated
  • All registered components are available in any template context by using its id: {{ component_id }}
  • Manage the registry state as you wish, have it be request-scoped - or not!

Nested Components

  • Pass components as fields to other components
  • Nested components are wrapped in an Object that provides:
    • .html - the rendered HTML string for simple inclusion
    • .props - access to the component instance and its properties
  • Works with single components, lists, and dictionaries

JavaScript Integration

  • Place a .js file next to your component template (e.g., button.js next to button.html)
  • JavaScript is automatically collected during rendering and bundled into a single <script> tag at the root level
  • Specify a custom JS filename with the js field

Extra HTML Templates

  • Include additional HTML files via the html field (list of file paths)
  • Each extra template is rendered and added to the context by its filename
  • Access rendered content via {{ filename.html }} in your main template

Technical Details

  • Type Safety: Pydantic models provide validation and IDE support
  • Template Engine: Jinja2 with FileSystemLoader (customizable)
  • Rendering: Components render via render() or automatically via __html__()
  • Context Management: Thread-safe context variables for registry and script collection
  • Required Fields: id (unique identifier)
  • Optional Fields: js (custom JS filename), html (list of extra HTML files)

Complete Example

# components/ui/button.py
from pyjinhx import BaseComponent

class Button(BaseComponent):
    id: str
    text: str
    variant: str = "primary"
<!-- components/ui/button.html -->
<button id="{{ id }}" class="btn btn-{{ variant }}">{{ text }}</button>
// components/ui/button.js
console.log('Button {{ id }} initialized');
# components/ui/card.py
from pyjinhx import BaseComponent
from components.ui.button import Button

class Card(BaseComponent):
    id: str
    title: str
    content: Button
<!-- components/ui/card.html -->
<div id="{{ id }}" class="card">
    <h2>{{ title }}</h2>
    <div class="card-body">
        {{ content.html }}
    </div>
    <div class="card-footer">
        {{ footer.html }}
    </div>
</div>
<!-- components/ui/footer.html -->
<p class="footer-text">© 2024 My App</p>
# Usage
from components.ui.card import Card
from components.ui.button import Button

action_btn = Button(id="action-1", text="Submit", variant="success")

card = Card(
    id="form-card",
    title="User Form",
    content=action_btn,
    html=["components/ui/footer.html"]
)

# Render the component
html = card.render()
# The card template can access:
# - Nested components via .html (e.g., {{ content.html }})
# - Component properties via .props (e.g., {{ content.props.text }})
# - Extra HTML templates via .html (e.g., {{ footer.html }})
# - Any registered component by ID (e.g., {{ action-1 }})
# - All JavaScript files bundled at the end
<!-- Render any component by ID in any template -->
<!-- page.html -->
<div>{{ form-card }}</div>

This example demonstrates nested components, extra HTML templates, the global registry, Object wrapping with .html and .props, automatic template discovery, JavaScript bundling, and rendering components by ID.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyjinhx-0.1.1.tar.gz (20.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyjinhx-0.1.1-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file pyjinhx-0.1.1.tar.gz.

File metadata

  • Download URL: pyjinhx-0.1.1.tar.gz
  • Upload date:
  • Size: 20.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for pyjinhx-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4d473326a2f0c2b62957dcbcaf85d5fe10ed7c95bf4f8cf902e151d1170f91a0
MD5 606fefa40a56ff20a13f38cd5061aeaf
BLAKE2b-256 124cdfd7d3d6430f6dbf313ffea8ce5556062bc440429f17e63fd9a191ff7859

See more details on using hashes here.

File details

Details for the file pyjinhx-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pyjinhx-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for pyjinhx-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e6a825e351204238a164cefefacbad020e4e5590937443e8f086ee0a5c5cc8d0
MD5 1b11cae7280d2e19285349b78f561213
BLAKE2b-256 8b84a5bd0fcfaf028e6a0977a5823389e5e2312a442ff79bee60fd1c9e0c9b6b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page