Modules

The framework is built from around one hundred and thirty small, single concern modules. Each one owns its own data objects, database access, services and user interface, and declares every module it depends on. An application is simply the list of modules it includes.

The sidebar lists every module, grouped into families by concern. The Database module is documented in full below as the reference example; the other pages follow the same shape.

Anatomy of a module

Every module is a folder with the same layout, so you can read one end to end in a few minutes and, once you have seen one, find your way around any of them.

Database/
  index.php     Requires dependencies, registers config, loads classes, connects
  README.md     Overview and dependency list
  class/        One class per file (Database, DatabaseQuery, DatabaseError, ...)
  database/     Query and data-object mapping helpers
  install/      Versioned schema scripts (0001.php, 0002.php, ...)

The index.php requires every module it uses directly at the top, registers the configuration it needs, then loads its own classes. Nothing is loaded for you behind the scenes, so the shape of an application is always visible in its includes.

Module families

The families below group the modules by concern. A family is just a grouping for the documentation; each module stands on its own and pulls in only the modules it actually uses.

Core and utility

The bootstrap and the building blocks: the module loader, the application shell, configuration and context, the console and command line, and the shared code and service helpers.

Types and data

The small pure helpers used everywhere: type checks and conversions, logic and maths, text and encoding, arrays and collections, filtering, colour and calendar.

System

The runtime services a site leans on: security and sessions, files and locks, processes and networking, background queues, scheduled jobs, state machines, logging and tracking.

Database and storage

Relational database access and caching, plus the content addressed object store with its blob backends and vendor drivers.

Web and interface

Routing and the declarative Ui library, layout and widgets, charts, permalinks and web-side tracking. All markup is built through the Ui library, never by hand.

WebUiLayoutWidgetChartPermalinkWebTracking

Members and auth

Membership, identity, verification and settings, folders and billing links, and the email and mobile sign-in methods, each its own small module.

Messaging

A messaging core with pluggable email, SMS and push notification providers, so a site swaps a provider without touching the code that sends messages.

Payments

A payment core with a Stripe provider. The core describes what a payment is; the provider connects it to the vendor.

Location

A location core with a service layer and a Google vendor for geocoding and lookups.

Cloud

A cloud core with Google and local vendor drivers, so the same calls run against a cloud provider or the local disk.

CloudCloudVendorGoogleCloudVendorLocal

Api and signals

HTTP Api endpoints, signal and websocket support, and the per-module Api surfaces that expose a module to the front end.

Admin and support

The admin framework and system admin tools, workflow admin, support and vendor management. Every diagnostic or maintenance tool lives here, behind authentication.

Localisation

Translation and site terminology, so the words on the page and the language a visitor sees are configuration, not hard-coded text.

Shared conventions

The same rules hold across every module, so a pattern you learn in one place transfers everywhere else:

  • Data moves through the system as small immutable data objects: fields and a constructor, no behaviour. Anything that can be absent is named so at a glance.
  • Each entity has one database class, and every query returns a data object through a single private mapper. Reads and writes are kept apart.
  • Tables from different modules are never joined in a query; modules are brought together in plain code instead.
  • All output is built with the declarative Ui library rather than raw markup, so there is one look across the whole system.
  • There are no developer or diagnostic features on public pages, and no hidden query flags. What is on the page is what a visitor is meant to see.