menu_book Navigation menu

Routing & URL Schemas

The Routing Engine (router.php) is the backbone of Pragma CMS. It acts as a comprehensive middleware pipeline that processes the request, enforces security, resolves the language, and executes the controller, all without querying the database for route matching.

Anatomy of a Pragma URL

TEXT
<https://domain.com> / fr / blog / tech / my-article ? utm_source=twitter
\\________________/   \\_/  \\______________________/   \\__________________/
     BASE_URL        Lang       Route Path             Query String
  • Language Prefix: Extracted automatically if it matches an active language code. Exceptions like /api or /admin bypass this requirement.
  • Route Path: The exact path mapped against the cached routes.

The Security Pipeline

Before any controller is executed, the router fortifies the HTTP response:

  1. CSRF Generation: A cryptographically secure 32-byte hexadecimal CSRF token is attached to the session.
  2. Dynamic CSP (Content Security Policy): The router generates a unique nonce ($GLOBALS['csp_nonce']) for the current request. This nonce must be used to execute any inline <script> tags, rendering XSS attacks virtually impossible.
  3. Strict Headers: Injects X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, and strict Referrer policies.
  4. Cache Control: Forces no-cache, must-revalidate to ensure dynamic HTML is never stale, while safely delegating asset caching (304 Not Modified) to the browser.

The High-Performance Cache Matching

Pragma CMS compiles all active routes into a highly optimized PHP array stored in storage/cache/routes/{langCode}.php. This eliminates the need for expensive database lookups on every page load.

The Validation Process:

  1. Regex Conversion: The router converts user-friendly patterns (e.g., blog/{slug}) into native Regular Expressions.
  2. HTTP Method Check: Rejects mismatches (e.g., POST requests on a GET-only route).
  3. Strict Dynamic Validation: If a route utilizes dynamic placeholders ({slug}), the router verifies the extracted value against the ContentTypeManager to ensure the entity actually exists. This prevents collisions between identical route structures (e.g., distinguishing /products/my-item from /blog/my-item).

Parameter Injection & Execution

Once the route is fully validated:

  1. The target controller file is resolved using resolveCascadingPath() (allowing Site overrides over Core files).
  2. The extracted URL parameters are safely injected directly into the $_GET superglobal.
  3. The $page->currentRoute object is populated, giving the developer immediate access to the route's handle, parameters, and Main Content Type context.