Madraset El Shamamsa, Part 3: The PHP Component-Rendering Pipeline
The most project-specific part of Madraset El Shamamsa is its PHP page-composition/rendering pipeline. It solves a practical publishing problem: many pages share the same shape, but each content library has its own records and presentation details.
It is not a general-purpose SSR framework. It is a convention-based system built inside this application, using PHP includes as composition boundaries.
From URL to complete HTML
flowchart TB
Entry["Thin page entrypoint"] --> Generator["Library-specific generate-* assembler"]
Generator --> Start["*-start.php context and data loader"]
Start --> DB[("MySQL or page-specific data")]
Generator --> Head["Metadata and head fragments"]
Generator --> Global["Shared navbar, breadcrumbs, footer, scripts"]
Generator --> Local["Library intro, body, media, navigation"]
Head --> Document["Complete server-rendered HTML document"]
Global --> Document
Local --> Document
Document --> Browser["Browser or crawler"]
The entrypoint identifies the page. The generate-* file defines the document structure for that family of pages. Its *-start.php dependency prepares variables and retrieves records. Shared components provide the global shell, while library components own the content-specific sections. PHP evaluates the graph on the server and sends an ordinary HTML document.
This pattern appears across hymn meditations, Coptic lessons, sermons, quotations, church-history articles, Bible summaries, and other libraries. Names differ because the system grew over time, but the recurring separation is visible in the codebase.
A representative, sanitized path
The real files contain library-specific names and fields. The following example keeps the control flow while removing operational detail:
<?php
// A thin content page delegates to its library assembler.
include __DIR__ . '/pageGeneration/generate-article.php';
<?php require __DIR__ . '/article-start.php'; ?>
<!doctype html>
<html lang="ar" dir="rtl">
<head>
<?php require $_SERVER['DOCUMENT_ROOT'] . '/common/head-includes.php'; ?>
<?php include __DIR__ . '/article-metadata.php'; ?>
</head>
<body>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/top-navbar.php'; ?>
<main>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/breadcrumb.php'; ?>
<?php include __DIR__ . '/article-body.php'; ?>
<?php include __DIR__ . '/article-navigation.php'; ?>
</main>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/footer.php'; ?>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/script-includes.php'; ?>
</body>
</html>

The important architectural interface is the set of variables prepared by the start/data loader and consumed by the fragments. That contract is currently conventional rather than enforced by a type system.
Why it scaled
One change can reach a page family. Updating a shared shell or a library assembler avoids copying the same document structure across many entrypoints.
The output is usable before JavaScript. Readers and crawlers receive headings, text, links, and metadata as HTML. JavaScript enhances the document instead of being required to create it.
Libraries remain independent where they need to be. A Coptic lesson does not have to pretend it has the same data model as a sermon or hymn. Each family can keep its body and navigation components while sharing global infrastructure.
Modern assets can arrive gradually. Shared script and head includes connect the generated document to Vite. The composition layer does not need to know whether a module came from the development server or a hashed production file.