SilverStripe调用renderWith无法覆盖默认Template如何解决?
问题根因
- 执行逻辑问题:
init()是控制器的初始化方法,仅用于执行初始化前置操作,你在此处调用renderWith()仅生成了渲染结果,但没有返回该结果也没有终止后续流程,控制器执行完init()后会继续走默认的动作渲染逻辑,最终返回默认模板的渲染结果,覆盖了你在init()中的操作。 - 写法冗余:当前控制器本身继承自
Controller,可以直接调用$this->getRequest()获取请求对象,不需要额外调用Controller::curr()获取当前实例。
修复方案
方案1:重写默认index动作(最常用,适配单页逻辑)
把模板切换逻辑放到默认的index动作中,直接返回渲染结果即可生效:
<?php namespace { use SilverStripe\CMS\Controllers\ContentController; class ForSalePageController extends ContentController { private static $allowed_actions = [ 'index' ]; protected function init() { parent::init(); } public function index() { $printVar = $this->getRequest()->getVar('print'); if ($printVar && $printVar === 'portrait') { return $this->renderWith('PrintPortrait'); } // 无匹配参数时走默认渲染逻辑 return []; } } }
方案2:适配多动作全局切换
如果该控制器下有多个自定义动作,希望所有动作都支持携带print参数切换模板,可以重写handleAction方法:
public function handleAction($request, $action) { $printVar = $request->getVar('print'); if ($printVar && $printVar === 'portrait') { return $this->renderWith('PrintPortrait'); } return parent::handleAction($request, $action); }
额外提示:修改代码后需要清空SilverStripe系统缓存,同时确认PrintPortrait.ss模板文件存放路径符合模板查找规则,可放在主题目录的templates/路径下或者自定义模块的templates/路径下。
内容的提问来源于stack exchange,提问作者user3425625
相关产品推荐
相关产品推荐

