我从CakePhp 2.x转到CakePhp 3.x
在CakePhp 2.x中,在我的ApiController中,我可以这样做:
public function getScript(){
$this->layout = 'empty';
$this->ext = '.js';
}
以上代码会呈现以下视图:
查看/原料药/ get_script.js (请注意.js扩展名)
如何使用CakePhp 3.x实现相同的行为?
我在文档中读到:
Controller :: $ ext属性已被删除。如果要使用非默认视图文件扩展名,现在必须扩展和覆盖View :: $ _ ext属性。
但我不明白如何以及在何处扩展View :: $ _ ext属性
我尝试了以下内容:
我在 src / View / ApiView.php中创建了一个新的View类
namespace App\View;
use Cake\View\View;
class ApiView extends View
{
protected $_ext = '.js';
}
在我的控制器中:
public function getScript(){
$this->viewClass='Api';
$this->layout = 'ajax';
}
但现在我收到以下错误:
错误:无法找到布局文件Layout / ajax.js 存在。
这是完全合理的,因为我告诉CakePhp使用.js作为默认扩展名。但我想使用.ctp扩展名作为布局,使用.js扩展名作为模板视图。
在CakePHP 2.x中这么简单我相信CakePHP3.x中也必须有一个简单的解决方案..请帮忙!
谢谢
答案 0 :(得分:3)
You can't have your cake and eat it (too)! The $_ext
property is being used for all template types (actions, elements, layouts), and its usage is buried in various different places, so changing this to be used selectively is a little tedious.
Your best bet would probably be to override View::_getViewFileName()
and change the extension temporarily, that's not very nice, but the least intrusive solution that comes to my mind right now:
protected function _getViewFileName($name = null)
{
$oldExt = $this->_ext;
$this->_ext = '.js';
$filename = parent::_getViewFileName($name);
$this->_ext = $oldExt;
return $filename;
}
答案 1 :(得分:2)
您可能希望使用RequestHandlerComponent进行内容类型协商,而不是使用模板扩展。这将允许您使用Template/Api/js/action.ctp
之类的目录。我发现这有助于保持API的各种响应格式干净,因为具有许多操作的控制器不会以庞大的视图文件列表结束。
要回答原始问题,您不能仅更改模板的扩展名,也不能更改默认视图类的布局。如果您想要这种行为,则需要自定义视图类。请查看_getViewFileName和_getLayoutFileName,了解要在子类中覆盖的方法。