Files
kennethreitz 71d4db055e Add PDF generation support and improve documentation
- Add WeasyPrint dependencies to Dockerfile for server-side PDF generation
- Update README with Quick Start guide for Docker and local development
- Add PDF template for article rendering
- Add error template for better error handling
- Reorganize photography into top-12 subdirectory
- Update pyproject.toml with PDF generation dependencies
- Enhance content.py with PDF rendering capabilities
- Improve directory template with gallery features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-01 15:17:43 -04:00

320 lines
9.5 KiB
Markdown

# TufteCMS
A Flask-based content management system designed for thoughtful writing, inspired by Edward Tufte's design principles. Built for digital gardens, essay collections, and content-rich websites that prioritize readability and deep engagement.
> **Note**: This repository is a hybrid containing both the TufteCMS framework (in `tuftecms/`) and Kenneth Reitz's personal website content (in `data/`). The CMS powers kennethreitz.org and serves as a living example of the system in production.
## Quick Start
### Option 1: Docker Compose (Recommended)
The easiest way to get started with all dependencies included:
```bash
# Clone the repository
git clone https://github.com/kennethreitz/tuftecms.git
cd tuftecms
# Start with Docker Compose
docker compose up
```
The site will be available at `http://localhost:8000` with hot-reloading enabled. All dependencies, including PDF generation, are pre-configured.
### Option 2: Local Development with uv
For local development without Docker:
```bash
# Clone the repository
git clone https://github.com/kennethreitz/tuftecms.git
cd tuftecms
# Install dependencies with uv (recommended)
uv sync
# Run development server
uv run python engine.py
```
The site will be available at `http://localhost:8000`
**Note**: PDF generation requires additional system libraries (see below). The site works fully without them - PDFs just won't be available.
### Installing uv
If you don't have `uv` installed:
```bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or via pip
pip install uv
```
## Philosophy
TufteCMS embraces **human-first design** - content presentation that serves readers' mental models rather than forcing adaptation to machine logic. It provides powerful features like sidenotes, content indexing, and cross-referencing while maintaining simplicity and elegance.
## Features
### Content & Typography
- **Tufte-style sidenotes** - Margin commentary without disrupting reading flow
- **Responsive typography** - Optimized for reading across all devices
- **Markdown rendering** - Custom Mistune renderer with philosophical code blocks
- **File-based content** - Simple directory structure mirrors URL routing
### Discovery & Navigation
- **Full-text search** - Relevance-scored search with contextual snippets
- **Content indexes** - Automatic extraction of sidenotes, quotes, outlines, connections, terms
- **Cross-referencing** - Track incoming/outgoing links between content
- **Theme detection** - Automatic categorization by content patterns
- **HTML & XML sitemaps** - Both human and machine-readable navigation
### Visual Identity
- **Generated SVG icons** - Unique algorithmic icons for every piece of content
- **Deterministic design** - Same title always produces the same icon
- **Dynamic folder icons** - Color variations based on content titles
- **Reading progress** - Visual indicator for longer essays
### Performance
- **Intelligent caching** - LRU caches for blog posts, indexes, and metadata
- **Background cache warming** - Async startup loading for instant response
- **Lazy loading** - Images load via IntersectionObserver
- **HTTP caching headers** - Aggressive caching for static assets
- **Cache debugging** - API endpoint to monitor cache performance
### Developer Experience
- **Flask blueprints** - Modular architecture with clear separation
- **API endpoints** - JSON APIs for search, icons, and debugging
- **RSS/Atom feeds** - Standard feed formats for syndication
- **Template system** - Jinja2 templates with extensible blocks
## PDF Generation Setup (Optional)
TufteCMS includes server-side PDF generation using WeasyPrint. This requires system libraries:
**macOS (via Homebrew):**
```bash
brew install cairo pango gdk-pixbuf libffi
```
**Ubuntu/Debian:**
```bash
sudo apt-get install libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info
```
**Docker:**
The provided Dockerfile includes these dependencies automatically.
**Note:** If you skip this step, the site will work fine but `.pdf` URLs will not function. All other features work without these libraries.
## Project Structure
```
tuftecms/
├── tuftecms/
│ ├── app.py # Application factory
│ ├── config.py # Configuration management
│ ├── blueprints/ # Route handlers
│ │ ├── main.py # Homepage and core routes
│ │ ├── content.py # Content rendering
│ │ ├── api.py # JSON API endpoints
│ │ └── feeds.py # RSS/sitemap generation
│ ├── core/ # Core functionality
│ │ ├── cache.py # Caching system
│ │ ├── content.py # Content processing
│ │ └── markdown.py # Markdown rendering
│ ├── utils/ # Utilities
│ │ ├── content.py # Content helpers
│ │ └── svg_icons.py # Icon generation
│ ├── templates/ # Jinja2 templates
│ └── static/ # CSS, images, fonts
├── data/ # Content directory
│ └── essays/ # Your content here
├── engine.py # Development server
└── pyproject.toml # Dependencies
```
## Content Organization
### Directory Structure
Content is organized in a simple directory structure under `data/`:
```
data/
├── essays/
│ ├── 2025-01-15-example-essay.md
│ └── 2025-02-20-another-essay.md
├── notes/
└── index.md
```
URL paths mirror the file system: `/essays/2025-01-15-example-essay`
### Writing with Sidenotes
Sidenotes provide commentary without disrupting reading flow:
```markdown
This is the main text.<label for="sn-example" class="margin-toggle sidenote-number"></label><input type="checkbox" id="sn-example" class="margin-toggle"/><span class="sidenote">This is a sidenote that adds depth without breaking the narrative.</span> The text continues naturally.
```
**Critical formatting rules:**
- Sidenotes must be inline (attached to sentence end with NO line breaks)
- Use descriptive IDs like `sn-consciousness`, `sn-recursion`
- Keep away from code blocks to prevent layout issues
### Markdown Features
```markdown
# Essay Title
*Published: January 2025*
Standard markdown with [links](/other-essay) and **emphasis**.
Code blocks with philosophy:
\`\`\`python
def consciousness():
# TODO: Model the unmappable
pass
\`\`\`
> Blockquotes for memorable passages
```
## Configuration
Edit `tuftecms/config.py`:
```python
class Config:
DISABLE_ANALYTICS = True # Privacy-first by default
SEARCH_CACHE_TIMEOUT = 60
DATA_DIR = "data"
MIN_SEARCH_QUERY_LENGTH = 2
MAX_SEARCH_RESULTS = 50
```
## API Endpoints
### Search
```
GET /api/search?q=query
```
Returns JSON with relevance-scored results, snippets, and match locations.
### Cache Debugging
```
GET /api/debug-cache
```
Returns cache statistics and LRU cache performance metrics.
### Icon Generation
```
GET /api/icon/<path:article_path>
```
Returns generated SVG icon data for any content path.
## Content Indexes
TufteCMS automatically builds indexes:
- **Sidenotes** - All margin notes with context
- **Outlines** - Heading structure across content
- **Quotes** - Blockquoted passages
- **Connections** - Internal link graph
- **Terms** - Key terms appearing across multiple articles
- **Themes** - Pattern-based content categorization
Access via routes: `/sidenotes`, `/outlines`, `/quotes`, `/connections`, `/terms`
## Deployment
### Docker
```bash
docker build -t tuftecms .
docker run -p 8000:8000 tuftecms
```
### Production with Gunicorn
```bash
uv run gunicorn -w 4 -b 0.0.0.0:8000 'tuftecms.app:create_app()'
```
### Environment Variables
```bash
DISABLE_ANALYTICS=true # Disable analytics
DEBUG=1 # Enable debug mode
```
## Development
### Debug Mode
```bash
DEBUG=1 uv run python engine.py
```
Enables verbose logging and development features.
### Cache Management
Clear all caches:
```python
from tuftecms.core.cache import clear_all_caches
clear_all_caches()
```
### Adding New Features
1. Create new blueprint in `tuftecms/blueprints/`
2. Register in `app.py`
3. Add templates to `tuftecms/templates/`
4. Update cache logic if needed in `core/cache.py`
## Philosophy & Design
TufteCMS is built on principles of **contemplative pragmatism**:
- **Human-first design** - Optimize for people having difficult days
- **Simple over clever** - Tools should feel natural to use
- **Content-focused** - Design serves the writing, not the ego
- **Respectful reading** - No dark patterns, no engagement manipulation
- **Open and inspectable** - Clean code, clear architecture
The name honors Edward Tufte's work on information design - presenting complex information with clarity and respect for the reader's intelligence.
## Use Cases
- **Digital gardens** - Personal knowledge bases that grow organically
- **Essay collections** - Long-form writing with depth and cross-references
- **Academic writing** - Papers with extensive sidenotes and citations
- **Documentation sites** - Technical docs with commentary
- **Philosophy blogs** - Contemplative writing with layered meaning
## License
MIT License - see LICENSE file for details.
## Credits
Created by Kenneth Reitz as part of kennethreitz.org. Built with Flask, Mistune, and care for human consciousness.
---
*"Technology should serve human mental models, not force humans to adapt to machine logic."*