Skip to content
TubePress — free, self-hosted & actively maintained
Developer reference

Architecture

The core layout, the request lifecycle and the no-framework conventions TubePress follows.

TubePress is a deliberately simple piece of software. There is no framework, no dependency-injection container and no build step — just well-organised, modern PHP using static classes. This page explains how the pieces fit together so you can extend the CMS confidently and know exactly where your code belongs.

Design philosophy

Three ideas shape the whole codebase:

  • No framework. Pure PHP with custom static classes. There are no Composer runtime dependencies to break and nothing to learn beyond PHP itself.
  • A fixed core, free add-ons. The core is updatable and should never be edited directly. Everything you customise lives in themes, plugins or settings.
  • Built to scale and to survive cheap hosting. Heavy work is chunked, and a built-in pseudo-cron means no system crontab is required.

Directory layout

The repository separates the core (fixed, updatable) from add-ons (installed and removed by users).

CORE — never modified by themes/plugins, replaced by updates
  config/            App config, DB config, install marker
  src/Core/          App, Database, Router, Pagination, CronManager,
                     and the managers (Seo, Transcode, Update, …)
  src/Auth/          Auth, Gate (permissions)
  src/Models/        Video, Category, Tag, Performer, Channel,
                     Comment, Page, User, Setting, Favorite, History
  src/Admin/         Admin CRUD controllers
  src/Front/         Public-facing controllers
  src/Install/       InstallController, Migrator
  src/Helpers/       Format, FileUpload, Sanitizer, Slug, SEO,
                     Player, RateLimiter, ImpressionTracker
  src/Plugin/        HookSystem, PluginInterface, PluginManager
  src/Theme/         ThemeManager, ThemeRenderer
  sql/               Numbered migrations (001_…sql → 0xx_…sql)
  templates/admin/   Admin panel templates (layout + partials)
  templates/install/ Install wizard templates
  public/            Web root — index.php, uploads/, symlinks
  cron/              Optional CLI scripts for a system crontab

ADD-ONS — installable / removable by users
  themes/            Theme directories (active: "simply")
  plugins/           Plugin directories (agegate, backup, ctr)
  lang/              Translation files (en, fr, de, es, ar, …)
Never edit the core to customise. Anything under src/, config/, sql/ or templates/ can be overwritten by an update. Put your changes in a theme or plugin so they survive.

The request lifecycle

Every request flows through public/index.php in the same order:

  1. PHP version guard. config/php-guard.php runs first — a parse-safe gate that stops boot on an unsupported PHP version before any modern syntax is loaded.
  2. Bootstrap. config/app.php sets up autoloading, the session and core services.
  3. Install check. If App::isInstalled() is false (no config/installed.php), the request is routed to the install wizard and nothing else loads.
  4. Route registration. Admin, API and front controllers each register their routes via a static ::routes() method.
  5. Dispatch. Router::dispatch() matches the URL and calls the controller method.
  6. Render. Admin actions render templates/admin/*; front actions render the active theme through ThemeRenderer::render().
  7. Post-render work. Impressions flush and CronManager::run() fires any due tasks.

Front page routes (the /{slug} catch-all for static pages) are registered last, so they never shadow real routes.

Core conventions

ConceptConvention
ControllersAdminXxxController::routes() / FrontXxxController::routes() register routes; methods handle requests.
ModelsStatic methods: Video::find($id), Video::all($filters), Video::create($data).
DatabaseDatabase::fetchOne(), fetchAll(), insert(), update(), delete(), count(), transaction().
RouterRouter::get(), Router::post(), Router::param('name'), Router::redirect().
Admin templatesRouter::render('admin/videos', […])templates/admin/videos.php (loads layout.php + a _videos.php partial).
Front templatesThemeRenderer::render('home', […]) → active theme template + its layout.php.
Migrationssql/NNN_name.sql, run automatically by Migrator::run() during install and update.
HooksHookSystem::doAction('event') and HookSystem::applyFilter('filter', $value).

Web server support

TubePress runs on both Apache and Nginx:

  • Apache.htaccess files handle URL rewriting and directory protection.
  • Nginxalias directives serve assets and deny all rules protect sensitive paths.
  • Symlinkspublic/themes → ../../themes and public/templates → ../../templates expose theme and admin assets while keeping PHP source outside the web root.

The web root is always public/. Everything sensitive — config/, src/, sql/, storage/ — sits outside it and is additionally blocked at the server level.

Where to customise

You want to…Do it in…
Change look & layoutA theme (or Appearance settings for no-code changes)
Add a feature or integrationA plugin using actions & filters
Change behaviour without codeSettings
Add scheduled workThe CronManager, from a plugin

Next steps

Still stuck?

Open a ticket from your dashboard and our team will help you out.

Try the live demo → Download TubePress →