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, …)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:
- PHP version guard.
config/php-guard.phpruns first — a parse-safe gate that stops boot on an unsupported PHP version before any modern syntax is loaded. - Bootstrap.
config/app.phpsets up autoloading, the session and core services. - Install check. If
App::isInstalled()is false (noconfig/installed.php), the request is routed to the install wizard and nothing else loads. - Route registration. Admin, API and front controllers each register their routes via a static
::routes()method. - Dispatch.
Router::dispatch()matches the URL and calls the controller method. - Render. Admin actions render
templates/admin/*; front actions render the active theme throughThemeRenderer::render(). - 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
| Concept | Convention |
|---|---|
| Controllers | AdminXxxController::routes() / FrontXxxController::routes() register routes; methods handle requests. |
| Models | Static methods: Video::find($id), Video::all($filters), Video::create($data). |
| Database | Database::fetchOne(), fetchAll(), insert(), update(), delete(), count(), transaction(). |
| Router | Router::get(), Router::post(), Router::param('name'), Router::redirect(). |
| Admin templates | Router::render('admin/videos', […]) → templates/admin/videos.php (loads layout.php + a _videos.php partial). |
| Front templates | ThemeRenderer::render('home', […]) → active theme template + its layout.php. |
| Migrations | sql/NNN_name.sql, run automatically by Migrator::run() during install and update. |
| Hooks | HookSystem::doAction('event') and HookSystem::applyFilter('filter', $value). |
Web server support
TubePress runs on both Apache and Nginx:
- Apache —
.htaccessfiles handle URL rewriting and directory protection. - Nginx —
aliasdirectives serve assets anddeny allrules protect sensitive paths. - Symlinks —
public/themes → ../../themesandpublic/templates → ../../templatesexpose 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 & layout | A theme (or Appearance settings for no-code changes) |
| Add a feature or integration | A plugin using actions & filters |
| Change behaviour without code | Settings |
| Add scheduled work | The CronManager, from a plugin |
Next steps
Still stuck?
Open a ticket from your dashboard and our team will help you out.