System Architecture

This document provides a high-level overview of the SmallBlock CMS architecture. It explains how the major components fit together, how requests flow through the system, and how SmallBlock remains extensible through plugins, templates, and runtime hooks.

This page is intended for:

  • developers administering a production SmallBlock deployment

  • contributors who want to extend or modify the system

  • readers evaluating SmallBlock’s design decisions

Overview

At its core, SmallBlock CMS is a modular, service-oriented Python application designed for clarity and extensibility. A typical deployment consists of:

  • A reverse proxy (usually Nginx) handling HTTP/S, TLS, and caching

  • The SmallBlock Application Server (Python), responsible for routing requests, rendering templates, executing plugins, and managing content

  • A database backend (PostgreSQL or MariaDB) storing pages, users, assets, translations, plugin metadata, and version history

  • Optional static asset serving (via the reverse proxy or a CDN)

  • Optional message broker / task runner for asynchronous operations

The architecture is intentionally simple to support installations ranging from small personal sites to high-traffic multi-language deployments.

High-Level Architecture Diagram

digraph Architecture {
    rankdir=LR;
    node [shape=box, style="rounded,filled", fillcolor="#eef3f8"];

    Browser [label="Web Browser\n(User)"];
    Nginx [label="Nginx Reverse Proxy\nTLS • Cache • Compression"];
    App [label="SmallBlock Application Server\nPython • Routing • Plugins • Templates"];
    DB [label="Database\nPostgreSQL or MariaDB"];
    Static [label="Static Assets\nCSS • JS • Media\nServed via Nginx/CDN"];

    Browser -> Nginx -> App;
    App -> DB;
    App -> Static [style=dashed, label="fetch static paths"];
    Nginx -> Static;
}

Request Lifecycle

  1. Browser Request — A visitor requests a page (e.g., /about/).

  2. Nginx Reverse Proxy - Terminates HTTPS - Applies caching rules - Serves static files directly (when possible) - Forwards CMS requests to the SmallBlock app server

  3. SmallBlock Application Server - Matches the request to a route or page - Loads page metadata and content from the database - Executes plugins - Resolves template tags - Applies language selection (if i18n is enabled)

  4. Template Renderer - Loads the selected theme - Injects context data (page, user, nav) - Produces final HTML

  5. Nginx Sends Response - Compresses - Delivers final HTML document

Application Server Internals

The application server is built on a lightweight Python web framework. Its responsibilities include:

  • Routing (mapping URLs to content)

  • Middleware processing

  • Template rendering

  • Plugin execution hooks

  • User authentication

  • Administration interface logic

  • Database session management

Internally, the server uses a clear hierarchy:

app/
├── core/            # Routing, middleware, request handlers
├── templates/       # Built-in templates
├── plugins/         # Plugin registry and helpers
├── models/          # ORM models (Pages, Users, Translations…)
├── static/          # Base JS, CSS, icons
└── utils/           # Helpers, cache tools, logging

Plugin Architecture

SmallBlock supports simple, powerful plugin development.

Plugins can:

  • Register template tags

  • Provide static assets (JS, CSS, images)

  • Add toolbar extensions

  • Add CLI commands

  • Hook into request/response events

A plugin is detected automatically if it contains a plugin.py file with a register(app) function.

Example:

def register(app):
    @app.template_tag("hello")
    def hello(name="World"):
        return f"Hello, {name}!"

Template Rendering Architecture

Templates follow a layered structure:

  1. Base Template — Defines the global layout

  2. Page Templates — Overrides for content types

  3. Partials — Reusable blocks (navbar, footer, etc.)

  4. Template Tags — Dynamic data from Python functions

Rendering flow:

digraph Templates {
    rankdir=TB;
    node [shape=box, style="rounded,filled", fillcolor="#eef3f8"];

    Base [label="base.html\n(Theme)"];
    Page [label="page.html\n(Content Type)"];
    Partials [label="partials/*.html"];
    Tags [label="Template Tags\nPython Functions"];
    Context [label="Context Data\n(page, nav, user, language)"];

    Base -> Page;
    Page -> Partials;
    Page -> Tags;
    Tags -> Context;
}

Database Architecture

SmallBlock uses a compact, normalized schema:

  • pages — URL, title, content, timestamps

  • users — accounts, roles, permissions

  • translations — i18n content

  • plugins — metadata and flags

  • media — file paths and metadata

All database interactions go through an ORM layer for portability.

Static Asset Handling

SmallBlock separates static assets from dynamic content:

  • Theme assets → themes/<theme>/static/

  • Plugin assets → plugins/<plugin>/static/

  • User uploads → media/

  • Global assets → app/static/

These should be served by Nginx or a CDN.

Scaling Considerations

Vertical Scaling

  • Add CPU/RAM

  • Enable caching

  • Move static assets to CDN

Horizontal Scaling

  • Run multiple app servers

  • Add load balancer

  • Use Redis for session storage

  • Use database replicas

Database Scaling

  • Connection pooling (pgBouncer)

  • Replication

  • Partitioning for large sites

Security Model

SmallBlock uses secure defaults:

  • Role-based permissions

  • CSRF protection

  • Content sanitization

  • Hashed passwords

  • Plugin sandboxing

  • Optional CSP enforcement

See Security Hardening for detailed guidance.

Next Steps