Core Dual Render ‐ Admin - xoopscube/legacy GitHub Wiki
XCL's Admin Render System Initialization
The XCL framework uses a sophisticated rendering system with different render systems for public and admin areas.
Let's keep refering to "core dual render" as a clear and descriptive term that gets the essential concept across
without relying on potentially fleeting JavaScript-centric buzzwords. It emphasizes the fundamental idea of having
a central rendering capability that operates in two key environments (server and client) for distinct advantages.
So, how the render system initialization works, particularly on the admin side where the magic operates.
Render System Architecture
XCL has two primary render systems:
- Legacy_RenderSystem - Used for public-frontend pages
- Legacy_AdminRenderSystem - Used for admin control panel
These render systems are defined in the site configuration (site_default.ini):
[RenderSystems]
Legacy_RenderSystem=Legacy_RenderSystem
Legacy_AdminRenderSystem=Legacy_AdminRenderSystem
[!NOTE] Certain bundle distributions feature or provide support for customized renders.
Render System Initialization Process
The initialization process follows these steps:
- The controller (Legacy_Controller) determines which render system to use based on the context
- It loads the appropriate render system class
- The render system creates render targets for different parts of the page (blocks, main, etc.)
- Preloads like AdminDashboard hook into this process to modify or extend functionality
Admin Render System Specifics
For the admin area, the process is:
Legacy_Controller
detects an admin request and setsLegacy_AdminRenderSystem
as the base render systemLegacy_AdminControllerStrategy
is initialized to handle admin-specific rendering- The strategy sets up admin blocks through its
mSetupBlock
delegate - Preloads like
AdminDashboard
hook into this process via delegates
The AdminDashboard Preload
Looking at the AdminDashboard.class.php
preload:
public function preBlockFilter()
{
$root=&XCube_Root::getSingleton();
// Add a delegate to the SystemCheck event
$root->mDelegateManager->add("Legacypage.Admin.SystemCheck",
"Legacy_AdminDashboard::AdminDashboardSystem",
XCUBE_DELEGATE_PRIORITY_1);
// Hook into the admin block setup process
if ($root->mController->_mStrategy &&
get_class($root->mController->_mStrategy) === 'Legacy_AdminControllerStrategy') {
$this->mController->_mStrategy->mSetupBlock->add([$this, 'AdminSetupBlock']);
}
}
This preload does two important things:
- It hooks into the
Legacypage.Admin.SystemCheck
delegate to add dashboard content - It hooks into the admin controller strategy's block setup process to add admin blocks
The Delegate System
The line that does the magic:
$root->mDelegateManager->add("Legacypage.Admin.SystemCheck", "Legacy_AdminDashboard::AdminDashboardSystem", XCUBE_DELEGATE_PRIORITY_1);
This registers the AdminDashboardSystem
static method to be called when the Legacypage.Admin.SystemCheck
event is triggered.
The priority (1) ensures it runs before other handlers.
Render Target Creation
When the AdminDashboardSystem
method is called, it creates content for the admin dashboard:
public static function AdminDashboardSystem()
{
$root =& XCube_Root::getSingleton();
if(XC_ADMINDASHBOARD_INFO) {
// Dashboard content creation logic...
// Create and render content using the render system
$attributes = [];
$attributes['title'] = $title1;
$attributes['content'] = $content1;
$template = XOOPS_LEGACY_PATH. '/admin/templates/dashboard.html';
self::display_message(false, $attributes, $template);
}
}
The Rendering Process
The actual rendering happens in the display_message
method:
public static function display_message(bool $return, array $attributes = [], string $template= '')
{
$root =& XCube_Root::getSingleton();
// Get the current render system
$renderSystem =& $root->getRenderSystem($root->mContext->mBaseRenderSystemName);
// Create a render target for the main content area
$renderTarget =& $renderSystem->createRenderTarget('main');
// Set module attribute
$renderTarget->setAttribute('legacy_module', 'legacy');
// Set template name
$renderTarget->setTemplateName($template);
// Add all attributes to the render target
foreach (array_keys($attributes) as $attribute) {
$renderTarget->setAttribute($attribute, $attributes[$attribute]);
}
// Render the content
$renderSystem->render($renderTarget);
// Return or print the result
if ($return == true) {
return $renderTarget->getResult();
}
print $renderTarget->getResult();
}
This method:
- Gets the current render system (in this case, Legacy_AdminRenderSystem)
- Creates a render target for the main content area
- Sets the template and attributes
- Renders the content
- Outputs the result
Admin Blocks Setup
The AdminSetupBlock
method adds blocks to the admin interface:
public function AdminSetupBlock() {
if (XC_ADMIN_BLOCK_MENU) {
require_once XOOPS_LEGACY_PATH . '/admin/blocks/AdminBlockMenu.class.php';
$this->mController->_mBlockChain[] = new Legacy_AdminBlockMenu();
}
// More blocks...
}
Each block is added to the controller's block chain, which is processed by the render system to create the final admin interface.
The Complete Flow
- Request comes in for an admin page
Legacy_Controller
initializes withLegacy_AdminControllerStrategy
- Preloads like
AdminDashboard
hook into the process - The controller processes the request and prepares data
- The
Legacy_AdminRenderSystem
creates render targets for different parts of the page - Delegates like
Legacypage.Admin.SystemCheck
are triggered - Preloads add content and blocks to the render targets
- The render system processes templates with Smarty
- The final HTML is output
This architecture allows for a highly modular and extensible admin interface where components like the dashboard
can be easily customized through preloads (single file comonent) without modifying core files.