Skip to main content

Pyxie

Create flexible websites with markdown content and FastHTML layouts - no design constraints.

Overview

Pyxie is a Python package that combines the simplicity of Markdown with the power of FastHTML to create modern, dynamic websites. Write your content in Markdown for maximum readability and maintainability, while leveraging component-based layouts for dynamic features. The result is content that's both beautiful to look at and semantically structured - making it ideal for both human readers and AI/LLM processing.

Features

  • Markdown-First: Write content in plain markdown with optional FastHTML components
  • Flexible Layouts: Define custom layouts with slots for different content sections
  • Content Management: Query and filter content using metadata
  • FastHTML Integration: Create dynamic components with Python

Quick Start

  1. Install Pyxie:
pip install pyx2
  1. Create a basic app (main.py):
from pathlib import Path
from fasthtml.common import *
from datetime import datetime
from pyxie import Pyxie

# Setup paths
BASE_DIR = Path(__file__).parent
CONTENT_DIR = BASE_DIR / "content"
POSTS_DIR = CONTENT_DIR / "posts"

# Initialize Pyxie
pyxie = Pyxie(
    POSTS_DIR,                             # Content directory    
    cache_dir=BASE_DIR / ".cache",         # Enable caching for better performance
    default_layout="default",              # Layout to use if not specified in metadata
    layout_paths=[BASE_DIR / "layouts"],   # Where to look for layouts    
)

# Create FastHTML app with Pyxie middleware
app, rt = fast_app(
    htmlkw=dict(lang="en"),
    middleware=(pyxie.serve_md(),)  # Serve markdown files at their slug paths
)

Key configuration options:

  • First argument is the content directory path
  • default_metadata: Default values for new posts (optional)
  • cache_dir: Enable caching for better performance (optional)
  • default_layout: Layout to use if not specified in metadata (defaults to "default")
  • layout_paths: Where to look for layouts (defaults to checking layouts, templates, static)
  • auto_discover_layouts: Whether to automatically find layouts (defaults to True)
  1. Create your content structure:
my-site/
├── content/
│   └── posts/          # Your markdown content
├── layouts/            # Your layout files
│   └── default.py      # Default layout
├── main.py            # App initialization
└── .cache/            # Generated cache files

Writing Content

Create markdown files with frontmatter metadata:

---
title: "My First Post"
date: 2024-03-19
layout: default
status: published
---

<featured_image>
![My Image](path/to/image.jpg)
</featured_image>

<content>
# Hello World

Regular markdown content here...

<fasthtml>
def Greeting():
    return H1("Welcome to my site!", cls="text-3xl font-bold")

show(Greeting())
</fasthtml>

More markdown content...
</content>

Creating Layouts

Layouts define the structure of your pages and what content sections (slots) are available:

@layout("default")  # Register as the "default" layout
def default_post_layout(metadata):
    """Basic blog post layout."""
    return Div(
        # Header with title
        H1(metadata.get('title', 'Untitled'), cls="text-3xl font-bold"),
        
        # Featured image slot - optional
        Div(None, data_slot="featured_image"),
        
        # Main content slot - required
        Div(None, data_slot="content", cls="prose"),
        
        # Optional conclusion slot
        Div(None, data_slot="conclusion"),
        
        cls="max-w-3xl mx-auto px-4 py-8"
    )

Key concepts:

  • Use @layout(name) to register a layout
  • data_slot="name" defines where content sections appear
  • data_pyxie_show="name" shows that element only when the named slot is filled
  • data_pyxie_show="!name" shows that element only when the named slot is empty
  • Access metadata from the markdown frontmatter

Querying Content

Pyxie provides a powerful API for querying content:

# Get recent published posts
recent_posts = pyxie.get_items(
    status="published",      # Filter by metadata
    order_by=["-date"],     # Sort by date descending
    per_page=5              # Limit results
).items

# Get posts by category
tech_posts = pyxie.get_items(
    category="tech",
    status="published"
).items

# Complex queries
featured_posts = pyxie.get_items(
    status="published",
    is_featured=True,
    order_by=["-date", "title"]  # Sort by date then title
).items

Query features:

  • Filter by any metadata field
  • Sort by multiple fields (prefix with - for descending)
  • Pagination support with per_page and page
  • Returns an object with items and pagination info

Learn More

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgements

This project is built on top of FastHTML, a powerful web framework for creating HTML applications with python code. FastHTML provides the core functionality for handling layouts and components in Pyxie. We're grateful to the FastHTML team and community for creating such an excellent foundation to build upon.

Metadata

Release files for pyx2 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyx2 0.1.3
File Size Uploaded
pyx2-0.1.3.tar.gz 231.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyx2 0.1.3
File Interpreter ABI Platform
pyx2-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 278.7 kB

Release files / pyx2-0.1.3.tar.gz

Download URL pyx2-0.1.3.tar.gz
Size 231.4 kB
Tags Source
SHA-256 checksum
How to use checksums
598ab6ef2f6a4be6268438120bb9d5ca1eae68378eb16ed02e7d9704170705b9
BLAKE2b-256 checksum
How to use checksums
5dafd1e46d02921a3dea6e372034c508597214ea89986d6c881748bcf7e6debe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 3, 2025.

Transparency log

Release files / pyx2-0.1.3-py3-none-any.whl

Download URL pyx2-0.1.3-py3-none-any.whl
Size 47.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7d926021e459c1caf6741d083a019d478a72c1232897f8f383ec010ef7e6b3c5
BLAKE2b-256 checksum
How to use checksums
098b8eb5d84098f9c5743f0d78b19de29f89a0e26996ae880c78894c8027a204
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 3, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page