redaxo/source
REDAXO is an easy-to-learn, flexible CMS/website framework. Build websites with custom modules and full control over input/output. Multilingual, highly extendable, and adaptable to your workflow, backed by an active community since 2004.
To integrate REDAXO Core into a Laravel-like workflow (or leverage its patterns in a Laravel project), start by:
Install via Composer (if using REDAXO directly):
composer require redaxo/source
For Laravel integration, treat REDAXO as a modular dependency and use its core utilities (e.g., rex_*) via service providers.
First Use Case: Database Abstraction
REDAXO’s rex_sql and rex_sql_table classes provide a lightweight ORM-like layer. Example:
use rex_sql::getInstance();
$db = rex_sql::factory();
$result = $db->getArray("SELECT * FROM pages WHERE id = ?", [1]);
Laravel Tip: Wrap this in a Laravel service class to maintain consistency with Eloquent.
Key Entry Points
rex namespace: Core utilities (e.g., rex_string, rex_file, rex_dir).rex_extension::register('EVENT_NAME', function($params) {
// Modify $params or trigger logic
});
rex_config or YAML files (e.g., config.yml with !env support).Demo Projects Clone the demo_base repo to explore REDAXO’s structure and workflows.
REDAXO treats everything as a "module" (even core features). Laravel developers can mirror this:
addons/ (like Laravel packages) with:
/addons/
└── my_addon/
├── boot.php # Laravel-style service provider
├── functions.php # Core logic (rex_* helpers)
└── templates/ # Twig/Blade-like templates
rex_extension::register('BOOT', 'my_addon/boot.php') to initialize.Leverage REDAXO’s Extension Points (EPs) for Laravel events:
| REDAXO EP | Laravel Equivalent | Example Use Case |
|---|---|---|
PAGE_BEFORE_RENDER |
View::composing |
Modify page output before rendering. |
MEDIA_LIST_QUERY |
Model::booting |
Filter media queries. |
SLICE_BE_PREVIEW |
View::composed |
Preview slice revisions. |
Example: Laravel-Style Event Listener
// In boot.php
rex_extension::register('PAGE_BEFORE_RENDER', function($params) {
$params['content'] = app()->make(MyModifier::class)->modify($params['content']);
});
Migrations: Use rex_sql_table for schema definitions:
$table = new rex_sql_table('my_table', [
'id' => ['type' => 'int', 'autoinc' => true],
'title' => ['type' => 'varchar', 'length' => 255],
]);
$table->create();
Laravel Tip: Generate Laravel migrations from REDAXO tables using rex_sql::getTableStructure().
Query Builder: Chain methods like Eloquent:
$db = rex_sql::factory();
$pages = $db->getArray("SELECT * FROM pages WHERE status = ?", [1])
->map(fn($row) => new PageModel($row));
REDAXO’s rex_file and rex_media classes handle uploads, MIME types, and storage:
// Upload a file (Laravel-style)
$file = rex_file::upload($_FILES['file'], 'uploads/');
if ($file) {
$media = rex_media::add($file->getPath());
// Store $media->getId() in DB
}
Laravel Tip: Use rex_media for file storage and Storage::disk() for Laravel’s filesystem.
REDAXO uses YAML for config (with !env support):
# config.yml
database:
host: !env DB_HOST
password: !env DB_PASSWORD
Load via:
$config = rex_config::get('database.host');
REDAXO’s rex_language handles translations:
// Define translations
rex_language::set('my_addon', 'en', ['greeting' => 'Hello']);
// Use translations
echo rex_language::get('my_addon', 'greeting');
Laravel Tip: Integrate with Laravel’s trans() helper by extending rex_language.
docker run --rm -it -v $(pwd):/app php:8.3-cli composer install
php:8.3 in your Docker setup if migrating.ClassNotFound errors:
addons/ or lib/ with proper boot.php registration.rex_extension::register('BOOT', 'path/to/autoloader.php') for custom PSR-4 loading.rex_config::set('BE_SESSION_TIMEOUT', 0);
rex_cache::delete() or rex_finder::ignoreUnreadableDirs(true) to avoid race conditions during cache clears.echo htmlspecialchars(rex_media::get($id)->getFileName(), ENT_QUOTES);
rex_sql::factory()->query() with bound parameters (never concatenate queries).rex_file::getMimeType():
$allowedTypes = ['image/jpeg', 'image/png'];
if (!in_array(rex_file::getMimeType($file), $allowedTypes)) {
throw new Exception("Invalid file type");
}
composer psalm:no-cache
print_r(rex_extension::getRegistered('*'));
rex_sql::setDebug(true);
rex_sql::getArray() with LIMIT for large datasets.PAGER to rex_media_service::getList() to avoid loading all media at once:
$media = rex_media_service::getList(null, null, null, ['PAGER' => ['page' => 1, 'perPage' => 20]]);
AppServiceProvider:
public function boot() {
$this->app->singleton('redaxo.db', function() {
return rex_sql::factory();
});
}
rex_template for backend templates and Blade for frontend:
// In a Laravel controller
$content = rex_template::get('my_template')->parse();
return view('frontend.layout', ['content' => $content]);
rex_user with Laravel’s Auth:
Auth::loginUsingId(rex_user::getCurrent()->getId());
| Error | Cause | Solution |
|---|---|---|
Class 'rex_*' not found |
Autoloader not registered | Add rex_extension::register('BOOT', ...) |
Deprecated: imagedestroy() |
PHP 8.5+ deprecation | Update to media_manager 2.18.1+ |
Session expired overlay |
BE_SESSION_TIMEOUT misconfig |
How can I help you explore Laravel packages today?