🛠️ Helpers
Helpers are global functions that simplify access to key components of the framework. They are wrappers around core classes and methods commonly used during development.
⚙️ modx()
Returns the global instance of modX.
$modx = modx();🧾 query(?string $table = null)
Opens a query builder on a table. The name goes without the prefix — the connection adds it. Called with no argument, returns the connection itself.
query('site_content')->where('template', 4)->get();
query(); // Illuminate\Database\MySqlConnection🧱 model(string $name)
Opens a query on an Eloquent model resolved under PageBlocks\App\Models\. Unlike query(), rows come back as models — with relations, casts and scopes.
model('PbResource')->published()->limit(10)->get();⚙️ config(string $key, $default = null)
Retrieves a value from the configuration.
$debug = config('app.debug', false);
// or
Config::get('app.debug', false)
?? $modx->getOption('app.debug', null, false);📁 Configuration files are stored in: core/App/config/
📥 request(string $key = '')
Returns the current HTTP request instance or a specific value.
$request = request(); // $request = Request::getInstance()
$name = request('name'); // $request->get('name');
request()->validate([...]); // $request->validate([...]);🌐 uri()
Returns the current URI without extensions and leading/trailing slashes.
$uri = uri();
// for example: /about.html → "about"
// /blog/post/ → "blog/post"🏷️ alias()
Returns the current page alias (the last part of the URI).
$alias = alias();
// например: /blog/post → "post"
// /about → "about"💾 cache(string $key, $value = null, int $ttl = 3600)
Gets or sets a cache value.
$data = cache('menu'); // $data = Cache::get('menu');
cache('menu', $items, 600); // Cache::set('menu', $items, 600);📤 response($content = '', int $status = 200, array $headers = [])
Creates and returns an HTTP response.
$response = response(); // Equivalent to new Response();
return response('OK'); // $response->text('OK');
return response(['status' => 'ok'], 200); // $response->json(['status' => 'ok']);📌 Automatically detects the type: text, json, or object.
✅ validate(array $data, array $rules, array $messages = [])
Runs data validation.
$validator = validate(
['email' => 'john@example.com'],
['email' => 'required|email']
);
// or
$validator = Validator::make($data, $rules, $messages);🖼️ view(string $template, array $params = [])
Renders a template with parameters.
view('components.card', ['title' => 'Dashboard']);
// or
View::make('components.card', ['title' => 'Dashboard']);🔁 redirect(...$args)
Creates a redirect response.
$redirect = redirect(); // $redirect = Redirect::getInstance();
redirect('/login'); // $redirect->to('/login');
redirect()->back(); // $redirect->back();🧭 route(string $name, array $params = [])
Generates a URL from a named route, carrying the current language prefix.
$url = route('post.show', ['id' => 10]); // /en/post/10Not the same as Route::route()
Route::route() is the bare path with no prefix — that is what route_path() gives you. Reaching for the facade instead of the helper is how links on /en/ end up pointing at the default language.
🌍 lang(string $key, array $replace = [], string $locale = '')
Retrieves a translated string.
lang('messages.welcome');
// or
Lang::get('messages.welcome');📁 Language files are stored in: core/App/lang/{locale}/
🔐 auth(string $context = '')
Checks if the user is authenticated in the given or current context.
if (auth()) {
echo 'You are authenticated';
}
// or
if (auth('en')) {
echo 'Authenticated in "en" context';
}🔁 Equivalent to:
$modx->user && $modx->user->isAuthenticated($context ?: $modx->context->key);❌ abort(int $code = 404, string $text = '')
Aborts execution and returns an error response.
abort(403, 'Access denied');
// or
response()->abort(403, 'Access denied')->send();📄 console($message, $array = [])
Writes to the MODX log. The second argument is printed with print_r — handy for an array.
console('Order failed', $payload);⚠️ dd($message, $array = [])
Not what you think. This is not Laravel's "dump and die": the page does not stop and nothing is printed to the screen. The function is identical to console() — it logs and carries on.
dd('got here', $data); // ends up in core/cache/logs/error.log🌍 Languages
| Function | What it returns |
|---|---|
language() | The current language, or null |
languages() | Every active language |
langs() | A ready set for a language switcher |
lang_url(string $uri = '') | An address carrying the current language prefix |
multilingual() | Whether multilingual is on |
context() | The language key, or the default context when there is none |
{if multilingual()}
{foreach langs() as $item}
<a href="{$item.url}">{$item.name}</a>
{/foreach}
{/if}🔀 route_path(string $name, array $parameters = [])
Builds the address of a named route — so you neither type it by hand nor hunt down every occurrence when the route moves.
route_path('cargo.show', ['id' => 42]);👤 profile()
The current user's profile as an array. A guest gets an empty array, and the result is remembered for the request.
Why not $modx->user
The MODX user row itself holds almost nothing: email, fullname and the extended fields live on the profile. profile() saves you a $user->getOne('Profile') every time.
🛡️ csrf()
A ready hidden field with the token, to drop into a form.
<form method="post">
{csrf()}
</form>🧾 lexicon($key, $namespace = '')
A string from the MODX lexicon. Given a namespace, it is loaded for you.
lexicon('pb_blocks', 'pageblocks');🔢 plural_form($number, array $forms)
Agreement between a number and a word. Three forms for Russian, two for English.
plural_form(5, ['товар', 'товара', 'товаров']); // товаров
plural_form(2, ['item', 'items']); // items🏳️ Site mode
| Function | What it does |
|---|---|
site_mode() | dev or prod |
is_dev(), is_prod() | The same thing, as a condition |
The mode comes from the pageblocks_site_mode setting; anything but dev reads as prod.
📚 Object lists
| Function | What it returns |
|---|---|
resources($ids = null, array $options = []) | MODX resources from site_content |
pbresources($ids = null, array $options = []) | Custom resources from pb_resources |
users($ids = null, array $options = []) | Users |
The same lists are available in templates as modifiers — see View.
🌐 http_post(string $url, $data = null, array $headers = [], int $timeout = 10)
A POST request outwards without wiring up curl yourself. Returns the response as an array.
http_post('https://api.example.com/hook', ['id' => 42], ['Authorization: Bearer …']);🕒 now(string $timezone = null)
The current moment as a Carbon instance — with all its date arithmetic.
now()->addDays(7)->toDateTimeString();🧷 asset(string $path)
URL of a file under assets/, versioned by its modification time:
{asset('themes/css/main.css')}
<!-- /assets/themes/css/main.css?v=1785440855 -->Sites are usually deployed without a build step and link their styles with no version, so a returning visitor gets fresh markup against a cached stylesheet. A ?v= taken from mtime fixes that without changing anything in the templates. If the file is not on disk you get the plain URL back, with no version.
For .css and .js a .min sibling wins
main.css becomes main.min.css when such a file exists and is no older than the source. So the template always links the readable name, and a site that never runs a build loses nothing.
The mtime check is the safety catch
Edit the source and forget to rebuild, and you get your fresh change unminified rather than the stale minified copy. Silently serving the old one would be worse.
It depends only on MODX constants, not on the site's App layer, so it works in any project running the component.