Version 1.4.0 marks the most significant architectural change since JekCMS launched. The language engine has been completely rewritten, cutting translation load time by 73% and adding right-to-left script support for Arabic and Hebrew. This release also ships with a redesigned admin interface, a new media library with bulk AVIF conversion, and an overhauled API authentication system.
The new language engine uses a lazy-loading approach: translation strings are parsed on demand rather than upfront. On a 12-language installation, this reduces the memory footprint per request from 18MB to 4MB and eliminates the 200–400ms parsing delay that appeared under load. The 73% improvement figure is measured on a production install with 4,800 translation strings across all active locales.
RTL Language Support
Right-to-left support required changes across both the admin panel and the default theme layer. Text direction is now a per-locale setting rather than a per-page option, which means switching the active language switches the layout direction site-wide without any additional configuration. The RTL_LANGUAGES constant in config/environment.php accepts an array of ISO 639-1 codes; Arabic (ar) and Hebrew (he) are pre-configured.
Async Media Processing
The media library now processes uploads in a background queue rather than synchronously. Bulk AVIF conversion — available from Settings › Media — converts all existing WebP files in batches of 50. Progress is shown in real time via a polling endpoint. The original WebP files are kept until the conversion is verified; deletion is a separate manual step.
JWT Authentication in v2 API
API authentication has moved from long-lived API keys to short-lived JWT access tokens (15-minute TTL) paired with 30-day refresh tokens. Existing integrations using the v1 API key flow continue to work through v1.6.0. New integrations should use the v2 token endpoint documented in the API changelog.
How Lazy-Loading Translations Work Under the Hood
The previous engine loaded every .json translation file at bootstrap, parsing them into a single associative array stored in memory for the request lifetime. With 12 active locales averaging 400 keys each, that meant 4,800 array entries consuming 18 MB before a single template was rendered. The new engine replaces this with a two-tier approach.
Tier 1: Namespace Registry
At bootstrap, the engine reads only the file list from config/translations/ and builds a lightweight namespace registry — a flat map of translation key prefixes to file paths. This costs roughly 12 KB of memory regardless of how many locales are installed. When a template calls __t('admin.sidebar.dashboard'), the engine looks up the admin namespace, loads admin.json for the active locale on demand, and caches the parsed result for the remainder of the request.
Tier 2: OPcache-Friendly Compiled Files
For production environments, the CLI command php tools/compile-translations.php converts JSON files into plain PHP return [] files. OPcache stores these in shared memory, eliminating JSON parse overhead entirely. The compiled output is stored in cache/translations/ and automatically invalidated when the source JSON file's modification time changes.
// Before (v1.3): all translations loaded upfront
$allTranslations = [];
foreach (glob(TRANSLATIONS_PATH . '/*.json') as $file) {
$allTranslations += json_decode(file_get_contents($file), true);
}
// After (v1.4): loaded on demand per namespace
function __t(string $key): string {
[$ns, $rest] = explode('.', $key, 2);
$locale = App::locale();
if (!isset(TranslationStore::$loaded[$locale][$ns])) {
TranslationStore::load($locale, $ns);
}
return TranslationStore::$loaded[$locale][$ns][$rest] ?? $key;
}
RTL Implementation Details
Supporting right-to-left languages required more than flipping a CSS direction property. The admin panel uses a separate admin-rtl.css stylesheet that overrides 142 layout declarations — margins, paddings, flexbox directions, and absolute positioning values. This file is conditionally loaded when the active admin locale is in the RTL_LANGUAGES array, avoiding any performance cost for LTR installations.
Bidirectional Text Edge Cases
Mixed-direction content (e.g., an Arabic paragraph containing an English brand name) requires dir="auto" on individual text containers rather than relying on the page-level direction. JekCMS's default themes apply this attribute to all <p>, <li>, and <h1>-<h6> elements inside the content area. Custom themes should follow the same pattern to avoid reversed punctuation in mixed-language posts.
Admin Interface Redesign
The v1.4.0 admin panel introduces a sidebar navigation pattern replacing the previous top-bar menu. Key improvements include:
- Collapsible sidebar with icon-only mode for small screens — saves 240px of horizontal space
- Per-section colour coding: blue for content, green for media, orange for settings, purple for analytics
- Keyboard shortcuts for the 8 most-used actions (Ctrl+N for new post, Ctrl+S for save, etc.)
- Real-time notification badge on the sidebar showing pending comments and failed API requests
- Dark mode toggle that persists across sessions via a cookie rather than a database setting
Upgrade Path and Compatibility
The recommended upgrade sequence is: back up the database, run php tools/migrate-1.4.php --dry-run, review the log, then run without the flag. Sites with custom themes should test the lazy-loading change by searching for any code that accesses the internal $translations array directly — that global no longer exists. All helper functions (__t(), __tc(), __tp()) work identically; only the internal loading mechanism changed.
Performance Benchmarks Before and After
We measured the v1.4.0 language engine against the v1.3 implementation on an identical 12-locale production dataset. Average page render time dropped from 312ms to 84ms on pages that reference fewer than 20 translation keys — which covers the majority of frontend templates.
Admin panel pages, which load significantly more strings, improved from 540ms to 190ms. Memory consumption per request fell from 18.2 MB to 4.1 MB on the frontend and from 24.6 MB to 9.3 MB in the admin panel. These numbers hold under concurrent load testing at 200 requests per second, confirming that the lazy-loading approach scales linearly rather than degrading under contention.