Repository source: docs/plans/archive/multi_site_config_step2_feature_description.md
Multi-Site Config — Step 2: Feature Description
Problem
One codebase must serve zenmemes.com and chouse.club as separately branded deployments (site name, default theme, composer copy) without hardcoding either site's identity into the code zenmemes already runs, and developers need to preview either site's branding locally without hand-editing shell config each time.
User Stories
As a site operator, I want each vhost to declare which site profile it serves so that zenmemes.com and chouse.club render correct branding without a code change per site.
As a developer, I want to switch the active site profile while running the app locally so that I can preview chouse's branding in the same checkout I use for zenmemes, without a second clone or a permanent shell export.
As the site owner, I want adding a future third site to require only a new profile entry, not new plumbing scattered through the app.
Core Requirements
A single registry holds one entry per site (name, default theme, composer copy) — one source of truth, mirroring the existing
ThemeRegistrypattern.The active profile resolves from an environment variable (
FORUM_SITE_ID), consistent with the existingFORUM_*precedent; an absent value defaults tozenmemes, so the current deploy is unaffected.Every hardcoded
SiteConfig::SITE_NAMEreference reads from the active profile instead.Local/dev runs support switching the active profile per-invocation (e.g. a one-line prefix or CLI convenience on
./v3 start) without editing persistent shell config, so both profiles can be previewed from one checkout.A vhost with a site ID that doesn't match its content/database paths is a misconfiguration, not a supported mode — no code attempts to reconcile the two automatically.
Shared Component Inventory
SiteConfig::SITE_NAMEis already the single choke point all callers go through (Application.php,TemplateRenderer.php,Host/FrontController.php,templates/pages/about.php) — this feature extends that existing accessor rather than introducing a parallel identity lookup.ThemeRegistrystays the canonical list of available themes; the new registry only adds a per-site default selection, it does not duplicate or replace theme definitions.No new UI surface is introduced — existing templates keep calling the same accessors, which now return per-site values.
Simple User Flow
Operator sets
FORUM_SITE_ID(plus the existing content/databaseFORUM_*vars) in a vhost's config.A request arrives; the app resolves the active profile once per request from that env var.
Every place that currently renders
SiteConfig::SITE_NAMEor picks a default theme uses the resolved profile's values instead.Locally, a developer selects a profile per run/session and sees the corresponding branding without touching the codebase.
Success Criteria
Zenmemes' deployed behavior (name, theme, copy) is unchanged with
FORUM_SITE_IDunset.Setting
FORUM_SITE_ID=chousechanges site name, default theme, and composer copy everywhere they currently render, with no remaining hardcodedzenmemesstring in the affected call sites.A developer can preview both profiles locally in the same checkout within a single session, without editing a persistent config file.