menu_book Navigation menu

Routing

Overview

In Pragma CMS, all HTTP requests are intercepted by a single entry point which passes them to the Core Router (router.php).

The Router integrates multiple elements (security, multilingualism, request parsing, and route matching to include the correct file). Here is the exact sequence of the routing lifecycle, broken down into its logical phases:

1. Security & Session Bootstrap

Before processing any content, the router secures the request and initializes sessions:

  • CSRF Protection: It generates a unique and secure CSRF token if one does not already exist in the session.
  • HTTP Security Headers: It configures strict HTTP security headers:
    • Generates a unique cryptographic nonce used to sign inline scripts safely ($GLOBALS['csp_nonce']).
    • Sets policies like Content-Security-Policy (CSP), X-Frame-Options, etc.
  • HTML Page Caching: Enforces cache-control headers (no-cache, must-revalidate) to handle browser caching behavior properly.
  • Admin Auto-Login: It handles the automatic login process ("Remember Me" cookie functionality) for the administration panel.

2. Request Parsing & Redirections

The router analyzes the incoming request and checks for immediate routing overrides:

  • Request Parsing: It analyzes the HTTP request by retrieving the full URI, extracting the relative path, and identifying the HTTP method used (GET, POST, etc.).
  • Redirections: It checks the database and handles HTTP redirections (Exact, Prefix, or Regex matches) if they have been defined by the user in the Admin interface.

3. Multilingual Management

The router completely bootstraps the multilingual context:

  • Retrieves the supported languages and the default language from the database.
  • Extracts the language code directly from the URL.
  • Handles exceptions (such as /api, /uploads, etc.) to ensure they do not require a language code in the URL.
  • Retrieves the active language ID needed for database translations.
  • Loads the static PHP UI translations for the defined languages from the server's lang/ directories (en.phpfr.php, etc.).

4. System State & Maintenance

  • System Notifications: It handles and registers system notifications specifically for logged-in administrators (e.g., missing extensions, available updates).
  • Maintenance Mode: It handles the presence (or absence) of the maintenance page, automatically bypassing it for API calls or logged-in administrators.

5. The Route Matching Engine

This is the core of the router. It loads the routing logic from the cache file (automatically generated by the "Routes" page in the admin interface). It then iterates directly through these cached routes, which are already translated, performing the following steps for each:

  • Regex Conversion: Converts the route pattern into a regular expression (e.g., 'blog/{slug}' becomes '#^blog/([^/]+)$#').
  • Comparison & Method Check: Compares the current URL against the regular expression and verifies if the current HTTP method is allowed.
  • Parameter Extraction: Extracts the URL parameters if present.
  • Content Validation: Validates the content before confirming the route (this prevents false positives when multiple route_pattern have the same number of placeholders). To do this, it checks the database to see if the URL segments have been processed in the route_segments table, and verifies if the slug actually exists for this specific content type via the ContentTypeManager. It then retrieves the main_content_type_handle, which is highly useful later in a page/controller.
  • Permissions: Stores the permission associated with the page (retrieved from the route cache) directly into the Page object ($page->permission).
  • Current Route Object: Stores ALL the current route information into $page->currentRoute (including the handlemain_content_type_handle, and URL parameters).
  • Global Variables: Adds the extracted URL parameters into the $_GET superglobal, making them readily available for pages/controllers (e.g., to retrieve a slug).
  • File Inclusion: Includes the associated PHP controller file using the resolveCascadingPath() function. This function allows path resolution by searching first in the site's directory, and then falling back to the CMS core directory (Override System).
  • 404 Fallback: If the loop finishes and no route is found, it safely displays a 404 error page.

Developer API: The $page->currentRoute Object

When your controller or template is finally loaded, the Router has already populated the global $page object with everything you need to know about the current request.

PHP
/**
 * Example content of $page->currentRoute for the URL: /fr/blog/tech/my-post
 */
array(3) {
  ["handle"] => string(19) "front.articles.show"
  ["main_content_type_handle"] => string(7) "article"
  ["params"] => array(2) {
    ["category"] => string(4) "tech"
    ["slug"] => string(7) "my-post"
  }
}

Accessing Route Information

Because the router injects extracted route parameters into $_GET, you can safely retrieve them natively in your controllers:

PHP
// Retrieve the slug parsed by the router
$currentSlug = $_GET['slug'] ?? null;

// Check the required permission set by the router
$requiredPermission = $page->permission;