ZF2 在渲染模板时想要截断控制器名称,为什么?

ZF2 wants truncated controller name when rendering template, why?

我正在创建一个名为 Template 的 ZF2 模块。见下文:

在我的 module.config.php 中,我的视图管理器和控制器配置如下:

return array(
// Telling where the views are
'view_manager' => array(
    'display_not_found_reason' => true,
    'display_exceptions'       => true,
    'doctype'                  => 'HTML5',
    'not_found_template'       => 'error/404',
    'exception_template'       => 'error/index',
    'template_map' => array(
        'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
        'template/my/index' => __DIR__ . '/../view/template/myctrl/index.phtml',
        'error/404'               => __DIR__ . '/../view/error/404.phtml',
        'error/index'             => __DIR__ . '/../view/error/index.phtml',
    ),
    'template_path_stack' => array(
        __DIR__ . '/../view',
    ),
),
// Mapping controller names to controller files
'controllers' => array(
     'invokables' => array(
         'Template\Controller\MyCtrl' => 'Template\Controller\MyController'
     )
 ),     

template_map 中,我必须使用 template/my/index 值而不是 template/myctrl/index,否则,我会收到以下错误消息:

Zend\View\Renderer\PhpRenderer::render:
    Unable to render template "template/my/index";
    resolver could not resolve to a file

为什么?

正如@JVestry 所说,这似乎是一个错误。所以,让我们先试试别的。

找到您的 templatemap_generator.php 文件。它应该在您的 ZF2/bin 文件夹中。导航到您的模块文件夹,例如Application 目录,src, view, config 文件夹所在的目录。打开一个终端并输入 php ../../vendor/ZF2/bin/templatemap_generator.php ZF 将在您的模块目录中创建一个模板映射。现在要使用此模板,只需修改您的 module.config.php 文件

return array(
// Telling where the views are
'view_manager' => array(
    'display_not_found_reason' => true,
    'display_exceptions'       => true,
    'doctype'                  => 'HTML5',
    'not_found_template'       => 'error/404',
    'exception_template'       => 'error/index',
    'template_map' => include __DIR__ . '/../template_map.php',
),
// Mapping controller names to controller files
'controllers' => array(
     'invokables' => array(
         'Template\Controller\MyCtrl' => 'Template\Controller\MyController'
     )
 ),

在你的myAction()

$view = new ViewModel();
$view->setTemplate("template/myctrl/index");

我调用 template/my/index 因为这是生成器将要生成的内容,但您可以随意重命名。

因此,这有点令人困惑,因为您在名为 'template' 的模块中呈现视图模板时遇到问题,但是,我认为这不是错误。

假设您不尝试从控制器渲染特定视图,ZF 将根据模块名称、控制器名称和动作名称确定要使用的视图。 (我不认为您在控制器 invokables 中使用的别名是相关的。)对于控制器,它将删除所有名称空间并删除 'Controller' 后缀(如果存在)。所以 template/my/index 就是你剩下的。

没有 使用 template_map (它是可选的,可以提高性能),但在您的情况下,因为您的视图文件夹被命名为 myctrl,只有使用模板地图将ZF寻找的内容映射到实际位置,渲染才有效。

我建议您将 myctrl 视图文件夹重命名为 my 并删除模板地图条目(暂时),然后一切都会正常进行。

您可以使用controller_map更精细地控制渲染模板的名称。

所以在你的情况下你可以这样做:

return array(
// Telling where the views are
'view_manager' => array(
    'display_not_found_reason' => true,
    'display_exceptions'       => true,
    'doctype'                  => 'HTML5',
    'not_found_template'       => 'error/404',
    'exception_template'       => 'error/index',
    'template_map' => array(
        'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
        'template/my/index' => __DIR__ . '/../view/template/myctrl/index.phtml',
        'error/404'               => __DIR__ . '/../view/error/404.phtml',
        'error/index'             => __DIR__ . '/../view/error/index.phtml',
    ),
    'template_path_stack' => array(
        __DIR__ . '/../view',
    ),
    'controller_map' => array(
        'Template\Controller\MyCtrl' => 'template/myctrl',
    ),
),
// Mapping controller names to controller files
'controllers' => array(
     'invokables' => array(
         'Template\Controller\MyCtrl' => 'Template\Controller\MyController'
     )
),

参见:https://github.com/zendframework/zf2/pull/5670