CakePhp 3.X非默认视图文件扩展名


CakePhp 3.x non-default view file extension

我从CakePhp 2移动。

在CakePhp 2。x,在我的ApiController中我可以这样做:

public function getScript(){
    $this->layout = 'empty';
    $this->ext = '.js';
}

上面的代码将呈现如下视图:

视图/Api/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中它是如此简单。我相信CakePHP3中一定有一个简单的解决方案。x太. .请帮助!

谢谢

鱼与熊掌不可兼得!$_ext属性被用于所有模板类型(动作、元素、布局),它的用法隐藏在不同的地方,所以改变它来有选择地使用有点乏味。

你最好的选择可能是覆盖View::_getViewFileName()并临时更改扩展名,这不是很好,但这是我现在想到的最不具侵入性的解决方案:

protected function _getViewFileName($name = null)
{
    $oldExt = $this->_ext;
    $this->_ext = '.js';
    $filename = parent::_getViewFileName($name);
    $this->_ext = $oldExt;
    return $filename;
}

与其使用模板扩展,不如使用RequestHandlerComponent来进行内容类型协商。这将允许您使用像Template/Api/js/action.ctp这样的目录。我发现这有助于保持API的各种响应格式干净,因为具有许多操作的控制器不会以庞大的视图文件列表结束。

回答你最初的问题,你不能只改变模板的扩展名,而不是默认视图类的布局。如果你想要那种行为,你需要一个自定义视图类。看一下_getViewFileName和_getLayoutFileName,它们的方法要在子类中重写。