Official website for the Python FOSDEM 2026 conference, built with Lektor.
- Static Site Generator: Lektor 3.3.10 (Flask-based)
- Python: 3.12.12
- Templates: Jinja2 3.1.2
- Frontend: Bootstrap 3.3.7
- Automation: Taskfile
- Deployment: Netlify (self-hosted)
- Python 3.12.12 (system installation or mise global)
- Task 3.45.4 (managed via
.tool-versions) - mise for tool version management (recommended)
This project uses mise for tool version management.
-
Install mise (if not already installed):
curl https://mise.run | sh # or on macOS: brew install mise
-
Install Task (from
.tool-versions):mise install
-
Install Python 3.12.12:
Python is managed separately to avoid Netlify mise conflicts:
# Option 1: System installation (simplest) # Follow your OS-specific instructions # Option 2: mise global (not in project .tool-versions) mise use -g [email protected]
Netlify uses mise internally and conflicts arise when .tool-versions specifies Python.
The project .tool-versions only contains Task to avoid these conflicts. Python is managed
via PYTHON_VERSION in netlify.toml for Netlify builds.
Task handles virtualenv creation and dependency installation automatically:
# Quick start (creates venv + installs deps + starts server)
task serve
# Or step by step:
task venv # Create virtual environment
task dependencies:install # Install dependencies
task serve # Start development serverNote: The Taskfile automatically creates .venv if it doesn't exist, so you can run task serve directly from a fresh checkout.
Start the development server with hot reload:
task serveThe site will be accessible at http://localhost:5000
Generate static files in the ./output/ folder:
task buildRemove build files:
task cleanCompile dependencies from requirements.in:
task dependencies:buildUpdate all dependencies to latest versions:
task dependencies:update# Run all tests
task test
# Run tests with coverage report (for future Python code)
task test:coverage
# Run linting checks
task lint
# Auto-format code
task format
# Run full CI suite (lint + test + build)
task ciThis project uses GitHub Actions for automated testing:
- On every push/PR: Runs linting, tests, and build validation
- Required checks: All tests must pass before merging PRs
- Coverage: Code coverage can be enabled for custom Python code in
packages/
See .github/workflows/ci.yml for the full CI configuration.
/
├── content/ # Content pages (.lr format)
│ ├── talks/ # Conference talks
│ ├── speakers/ # Speaker profiles
│ └── ...
├── templates/ # Jinja2 HTML templates
│ └── blocks/ # Flow block templates
├── models/ # Schema definitions (.ini)
├── flowblocks/ # Reusable content block types
├── databags/ # Static data collections
├── packages/ # Custom Lektor plugins
├── assets/ # Static files (CSS, images)
├── output/ # Generated static site (ignored by git)
└── .venv/ # Python virtual environment
Content files use the .lr (Lektor Record) format:
_model: page
---
title: My Page
---
body:
#### md-section ####
title: Section Title
----
content: Markdown content here---separates fields####separates flow blocks- Directory hierarchy = URL structure
If you need more control:
# Server with specific options
.venv/bin/lektor serve --verbose --prune
# Build to custom output directory
.venv/bin/lektor build --output-path=/path/to/output
# Clean cache
.venv/bin/lektor cleanThe site is automatically deployed to Netlify when pushing to the main branch. Netlify:
- Detects changes on the GitHub repository
- Installs Python 3.12.12 and dependencies
- Runs
lektor build - Publishes the
output/folder content
No manual action is required for deployment.
- Create a folder in
/content/, e.g.,/content/my-page/ - Add a
contents.lrfile with thepagemodel - Add content using flow blocks (md-section, location, etc.)
- Optional: add to navigation in
/databags/menu.ini
- Create
/content/speakers/speaker-name/contents.lrwith thespeakermodel - Create
/content/talks/talk-title/contents.lrwith thetalkmodel - Link the talk to the speaker via the
authorfield
- humanize_date: Jinja2 filter to format dates (e.g., "January 01, 2026")
- Lektor Documentation
- Jinja2 Documentation
- CLAUDE.md - Detailed guide for Claude Code
The PythonFOSDEM.lektorproject file contains site configuration:
- Project name and event date
- GitHub and Twitter URLs
- CFP (Call for Proposals) dates
To contribute to the site:
- Fork the project
- Create a branch for your feature
- Test locally with
task serve - Submit a Pull Request
See the LICENSE file for more information.