My Design Choices For Websites Generator
This is a small blog where I explain some of my design choices for my website generator.
It is also a demonstration of the project itself, since this blog post (and the website you are reading it on) is generated by the tool.
1. Why I Built It
I wanted to learn how static site generators work internally and design one myself, with a focus on:
- Flexibility → supporting different site types like blogs, shops, portfolios.
- Extensibility → making it easy to add new features through plugins.
- Clarity → keeping the codebase small but structured enough to be maintainable.
This project also serves as a portfolio project for my resume, to show my understanding of design patterns and architecture.
2. The Core Abstractions
I designed three main building blocks:
-
Page
Represents a single page (Markdown, HTML, or other). It holds metadata, content, and output paths.
I added attributes likeslug
,page_type
, andoutput_path
so the generator can reason about where and how to render the page. -
Site
Holds all pages, global metadata, and exposes methods likeget_pages()
.
This makes it easy to query pages (for example, a plugin can find all pages with typeblog
). -
Project
Orchestrates everything: configuration, loading pages, running plugins, and rendering.
By separating "orchestration" (Project) from "data" (Site, Page), the design stays modular.
3. The Plugin System
Instead of hardcoding features like a blog index or RSS feed, I added a plugin system.
Plugins can hook into lifecycle events:
on_config_loaded
on_before_build
on_page_parsed
on_after_build
For example, my BlogIndexerPlugin searches for all pages with type: blog
and automatically generates a blog index page.
This pattern is common in real-world projects (like Jekyll, Hugo, and MkDocs) because it balances simplicity with extensibility.
4. Content Processors and Template Engine
To process different input formats (Markdown, HTML, etc.), I added a ContentProcessor factory.
This way, supporting new formats in the future (e.g., reStructuredText or AsciiDoc) will be as simple as writing a new processor class.
Rendering is done through a Template Engine factory, which abstracts away the underlying templating engine (like Jinja2).
This allows swapping or upgrading templating logic without changing the rest of the system.
5. Tradeoffs I Made
- Focused on clarity over optimization → since this is a learning project and a resume showcase, readability was more important than micro-optimizations.
- YAML config → I chose YAML for config files because it’s widely used in static site generators and is more readable than JSON for non-developers.
6. What I Learned
Through this project I practiced:
- Designing modular, extensible systems.
- Using factories and plugins to decouple responsibilities.
- Writing cleaner Python with logging, type hints, and tests.
- Building something practical enough to showcase.
7. What’s Next
- Add more plugins.
- Improve test coverage.
- Deploy this demo site to show the generator in action.
This project is not just code, but also a learning journey.
By writing it this way, I can confidently put it on my resume and talk about my design reasoning in interviews.