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_Controllerdetects an admin request and setsLegacy_AdminRenderSystemas the base render systemLegacy_AdminControllerStrategyis initialized to handle admin-specific rendering- The strategy sets up admin blocks through its
mSetupBlockdelegate - Preloads like
AdminDashboardhook 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.SystemCheckdelegate 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_Controllerinitializes withLegacy_AdminControllerStrategy- Preloads like
AdminDashboardhook into the process - The controller processes the request and prepares data
- The
Legacy_AdminRenderSystemcreates render targets for different parts of the page - Delegates like
Legacypage.Admin.SystemCheckare 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 component) without modifying core files.