Core Dual Render ‐ Frontend - xoopscube/legacy GitHub Wiki

The Complete Flow for Frontend Rendering in XCL

The frontend rendering process in XCL follows a similar pattern to the admin side, but with some key differences.
Here's how the flow works for a typical module page request:

Frontend Rendering Flow

  1. Request Initialization

    • Request comes in for a module page
    • mainfile.php bootstraps the system
    • XCube_Root singleton is created
  2. Controller Initialization

    • Legacy_Controller initializes with Legacy_PublicControllerStrategy (not AdminControllerStrategy)
    • The strategy determines how to handle public-frontend pages
  3. Preload Execution

    • System preloads are executed
    • Module-specific preloads are executed
    • Preloads can hook into various parts of the process using delegates
  4. Module Execution

    • The controller identifies the requested module
    • Module's xoops_version.php is loaded
    • Appropriate module action is determined (based on URL parameters)
    • Module action class is instantiated and executed
  5. Render System Initialization

    • Legacy_RenderSystem is initialized (not AdminRenderSystem)
    • Render targets are created for different parts of the page:
      • Main content area
      • Blocks (left, right, center-top, center-bottom)
      • Header, footer
  6. Delegate Triggers

    • Various delegates are triggered at different points:
      • Module.{ModuleName}.Event.{EventName}
      • Legacy.Event.{EventName}
      • Site.Event.{EventName}
  7. Block Rendering

    • Block positions are determined
    • Block content is generated
    • Blocks are assigned to their positions in the template
  8. Template Processing

    • Module template is loaded
    • Theme template is loaded
    • Smarty processes all templates
    • Variables are replaced with actual content
  9. Final Output

    • Complete HTML is generated
    • Output is sent to the browser

Key Differences from Admin Flow

The main differences between frontend and admin rendering are:

  1. Strategy Class:

    • Frontend: Legacy_PublicControllerStrategy
    • Admin: Legacy_AdminControllerStrategy
  2. Render System:

    • Frontend: Legacy_RenderSystem
    • Admin: Legacy_AdminRenderSystem
  3. Block Handling:

    • Frontend: Blocks are loaded from database based on visibility settings
    • Admin: Blocks are defined programmatically in preloads
  4. Templates:

    • Frontend: Uses theme templates + module templates
    • Admin: Uses admin theme templates
  5. Delegates:

    • Frontend has additional delegates for theme processing

Example of Frontend Flow with Code References

Here's a more detailed look at how the frontend flow works with code references:

// 1. Request comes in, mainfile.php bootstraps the system
include_once XOOPS_ROOT_PATH.'/include/cubecore_init.php';

// 2. XCube_Root singleton is created and controller is initialized
$root =& XCube_Root::getSingleton();
$root->setupController();
// Legacy_Controller with Legacy_PublicControllerStrategy is initialized

// 3. Preloads are executed
// In Legacy_Controller::_setupPreloads()
$this->_mPreloadManager->triggerEvent('PreBlockFilter');

// 4. Module is executed
// In Legacy_Controller::_setupModule()
$moduleRunner = new Legacy_ModuleRunner();
$moduleRunner->setActionName($this->mContext->mRequest->getRequest('action'));
$moduleRunner->setModuleName($this->mContext->mRequest->getRequest('dirname'));

// 5. Render system is initialized
// In Legacy_Controller::_processModule()
$renderSystem =& $this->getRenderSystem($this->mContext->mBaseRenderSystemName);
$renderTarget =& $renderSystem->createRenderTarget('main');

// 6. Module action is executed
// In Legacy_ModuleRunner::execute()
$action = new $actionName();
$action->execute();
$action->executeView($renderTarget);

// 7. Blocks are rendered
// In Legacy_PublicControllerStrategy::_processBlock()
foreach ($blockProcedures as $procedure) {
    $block = $procedure->getBlock();
    $renderTarget =& $renderSystem->createRenderTarget('block');
    $block->execute($renderTarget);
}

// 8. Templates are processed
// In Legacy_RenderSystem::render()
$smarty = new XoopsTpl();
foreach ($target->getAttributes() as $key => $value) {
    $smarty->assign($key, $value);
}
$result = $smarty->fetch($target->getTemplateName());

// 9. Final output is sent
echo $result;

This flow demonstrates how XCL handles frontend requests, from initial bootstrap to final output.
The modular architecture allows for extensive customization at various points in the process through the delegate system.