Handling Data
Pragma CMS is designed to stay out of your way. We deliberately avoid heavy ORM layers that obscure performance and generate unpredictable database queries. Instead, we provide a clean separation between Context Objects, Static Managers, and Global Helpers that act as a high-performance API for your site.
PHP: The Global Context Objects
Whenever a controller or template is loaded, Pragma CMS automatically injects global objects that represent the current state of the application. You do not need to fetch these; they are simply available.
$site: Contains global configurations, the current active language code, and fallback settings (e.g.,$site->url,$site->langCode,$site->settings['admin_email']).$page: Represents the current route's context. It holds the active view data, SEO metadata, breadcrumbs, and dynamic URL parameters (e.g.,$page->currentRoute['params']['slug']).
PHP: The Manager Pattern
To actually retrieve data from the database, Pragma uses specialized Static Managers. These classes automatically handle SQL preparation, security filtering, JSON decoding, and multi-language mapping.
Core Managers Cheat Sheet
| Manager | Primary Use | Example Methods |
|---|---|---|
| ContentTypeManager | Managing schema structures. | ContentTypeManager::get($handle) |
| EntryManager | Fetching dynamic content (Articles, Products). | EntryManager::getEntryBySlug(), EntryManager::getEntries() |
| PageManager | Retrieving static or builder-based pages. | PageManager::getPageBySlug() |
| MediaManager | Accessing file metadata and variant paths. | MediaManager::getMediaById() |
| TaxonomyManager | Fetching categories, tags, and structure. | TaxonomyTermManager::getTermsForObject() |
| UserManager | Accessing profiles and permission checks. | UserManager::getUsers(), UserManager::getUserById() |
| BreadcrumbManager | Managing hierarchical site paths. | BreadcrumbManager::renderBreadcrumbs() |
| FormManager | Rendering frontend forms. | FormManager::renderForm() |
| SeoManager | Injecting metadata and JSON-LD. | SeoManager::configureForSingleEntry() |
Additional specialized managers are available in the PHP API.
See the PHP API Reference section below for the full list.
Common Pattern: Displaying a Portfolio Landing Page
Here is how Context Objects ($page) and Managers (PageManager, EntryManager) work together in a typical controller:
<?php
/**
* Custom Controller: /sites/<your-site>/pages/portfolio.php
*/
// 1. Fetch data for the current page using the slug 'portfolio'
// Note: $_SESSION['lang_id'] is automatically handled by the Core Bootstrap.
$slug = $page->currentRoute['params']['slug'] ?? 'portfolio';
$pageData = PageManager::getPageBySlug($slug, $_SESSION["lang_id"]);
if (!$pageData) {
// If the user deleted the page in the admin, show 404
displayError(getTranslation("Not Found"), 404);
exit;
}
// 2. Add your custom business logic
// Example: Fetching 12 projects from the 'projects' collection
$projects = EntryManager::getEntries('projects', ['limit' => 12]);
// 3. Prepare View Data
$page->entry = $pageData;
$page->viewData["title"] = $pageData["title"];
$page->viewData["projects"] = $projects;
// 4. Set SEO & Breadcrumbs (Standard Helpers)
// This automatically sets <title>, meta description, and OpenGraph tags based on Admin data.
$page = SeoManager::configureForSingleEntry($page, $pageData, $site, $page->currentRoute['handle'], $_SESSION["lang_id"]);
// 5. Render
$page->header = renderHeader($page);
$page->footer = renderFooter($page);
$page->template = $pageData['template_path'] ?? "portfolio.php"; // Looks in your active theme /templates/
$page->main = render_template($page->template, $page);
echo render_template("base.php", $page);
PHP: The Database Class (Raw SQL)
When building Custom Extensions or querying custom tables that are not part of the standard CMS content types, you should bypass the Managers and use the Database class directly.
It is a secure, static wrapper around PHP's PDO, ensuring all queries use prepared statements to prevent SQL injection.
Reading Data (Select)
// Fetch multiple rows (Returns an array of associative arrays)
$activeUsers = Database::fetchAll(
"SELECT * FROM custom_bookings WHERE status = :status ORDER BY created_at DESC",
['status' => 'confirmed']
);
// Fetch a single row (Returns an associative array or null)
$booking = Database::fetch(
"SELECT * FROM custom_bookings WHERE booking_id = :id",
['id' => 142]
);
// Fetch a single column value directly (Returns a string/int or false)
$totalRevenue = Database::fetchColumn(
"SELECT SUM(price) FROM custom_bookings WHERE status = :status",
['status' => 'paid']
);
Writing Data (Insert, Update, Delete)
Use Database::updateTable() for any query that modifies data. It automatically handles the execution and returns a boolean.
$success = Database::updateTable(
"INSERT INTO custom_bookings (user_id, total, status) VALUES (:user, :total, :status)",
[
'user' => 12,
'total' => 250.00,
'status' => 'pending'
]
);
if ($success) {
$newId = Database::lastInsertId();
} else {
$error = Database::getError(); // Returns PDO error info [SQLSTATE, Code, Message]
}
Transactions
For complex operations requiring atomicity, wrap your queries in a transaction:
Database::beginTransaction();
$insert1 = Database::updateTable("...");
$insert2 = Database::updateTable("...");
if ($insert1 && $insert2) {
Database::commit();
} else {
Database::rollBack();
logError("Transaction failed.");
}
PHP Global Functions
To accelerate development, Pragma CMS exposes a set of globally available helper functions (functions.php) accessible from any controller, extension, or template.
Routing & URLs
getLink(string $routeHandle, array $params = [])
Dynamically generates a translated URL based on the route handle. It automatically handles the active language prefix.
// Returns: https://domain.com/en/blog/my-article
echo getLink('front.articles.show', ['slug' => 'my-article']);
getAssetsPath(string $path, bool $isTheme = false, ?string $extension = null)
Resolves the correct public URL for CSS/JS assets, handling the fallback priority (Theme > Site > Core).
Templating & UI
render_template(string $templateRelativePath, array|object $data = [])
Automatically detects and renders either a.twigor native.phptemplate, following the CMS hierarchy override rules.renderImage(int|array $mediaData, string $sizeSuffix = 'large', array $attributes = [])
Outputs a fully optimized<picture>HTML tag, automatically serving AVIF/WebP formats with the correctsrcsetattributes for Core Web Vitals optimization.renderIcon(string $library, string $name)
Generates the SVG or Font icon HTML based on the library (e.g.,material-symbols-outlined,fa-solid).
Utilities & API
getTranslation(string $key, array $params = [])
Fetches the localized string from the dictionary. Supports variables injection (['name' => 'John']) and pluralization.generate_slug(string $text, ?array $uniquenessCheck = null)
Generates a clean, URL-friendly string. Can automatically query the database to guarantee uniqueness by appending a numerical suffix if a collision occurs.sendJsonResponse(bool $success, ?string $message = null, $data = null, int $httpCode = 200)
The universal exit point for API endpoints. It cleans the output buffer, sets the correctapplication/jsonheaders, and enforces a standard JSON schema structure.
JavaScript Global Functions
In modern web development, many front-end features (infinite scroll, live filters, dynamic modals, headless interactions) require fetching data without reloading the page. Pragma CMS includes native, lightweight wrappers around the JS Fetch API.
The apiRequest Utility
apiRequest is the universal engine for all AJAX calls in the CMS.
Why use apiRequest instead of native fetch()?
- Error Handling: It natively parses JSON, catches HTTP errors (4xx, 5xx), and automatically triggers UI popups (
displayErrorPopup()) if something goes wrong. - Multiple Formats: It seamlessly handles
"json","html"(for DOM injection), and"blob"(for file downloads). - Smart Headers: Automatically injects the
X-Requested-With: XMLHttpRequestheader. - Loader Integration: Connects to
showLoader()to provide visual feedback.
Usage Example: Submitting data or loading HTML
// Example 1: Fetching JSON data
const response = await apiRequest('/api/custom-endpoint', {
method: 'POST',
body: JSON.stringify({ action: 'update_status' })
});
if (response && response.success) {
console.log(response.data);
}
// Example 2: Fetching an HTML fragment for a modal
const htmlFragment = await apiRequest('/api/modals/user-card?id=1', {}, null, 'html');
if (htmlFragment) {
document.getElementById('modal-container').innerHTML = htmlFragment;
}
The apiFetch Utility
For strictly querying CMS content (Entries, Taxonomies, Users), Pragma provides apiFetch. It is built on top of apiRequest and specifically formats URLs with search parameters, language context, and extra filters.
Usage Example: Loading categories with a live search
// apiFetch(endpoint, searchTerm, langId, extraParams)
const searchInput = "tech";
const langId = 1; // e.g., English
const response = await apiFetch("taxonomies/blog_category/terms", searchInput, langId, {
root_term_id: 12,
limit: 10
});
if (response) {
// response.data is guaranteed to be present if the call succeeds
renderDropdown(response.data);
}
API Reference
Explore the PHP API Reference
Explore the JS API Reference