Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 未找到Catalyst模板工具箱模板返回404_Perl_Http Status Code 404_Catalyst_Template Toolkit - Fatal编程技术网

Perl 未找到Catalyst模板工具箱模板返回404

Perl 未找到Catalyst模板工具箱模板返回404,perl,http-status-code-404,catalyst,template-toolkit,Perl,Http Status Code 404,Catalyst,Template Toolkit,我正在尝试创建一个对我的设计师来说非常灵活的应用程序。我的意思是,如果他们需要添加一个包含静态内容的新页面,我不必进入Catalyst并添加该操作,他们就可以为页面创建模板。我有它,如果他们添加任何名为name.html的模板,那么Catalyst应用程序可以显示http://www.domain.com/name.html即使没有名称操作。目前,我在根控制器中有一个子例程,如下所示: sub any_template :Regex('(.+)\.html$') { my ($self

我正在尝试创建一个对我的设计师来说非常灵活的应用程序。我的意思是,如果他们需要添加一个包含静态内容的新页面,我不必进入
Catalyst
并添加该操作,他们就可以为页面创建模板。我有它,如果他们添加任何名为
name.html
的模板,那么
Catalyst
应用程序可以显示
http://www.domain.com/name.html
即使没有
名称
操作。目前,我在根控制器中有一个子例程,如下所示:

sub any_template :Regex('(.+)\.html$') { 
    my ($self, $c) = @_; 
    $c->stash(
        template => $c->action . '.html',
    );
}
这使得任何以“.html”结尾的请求都会查找该名称的模板。但是,如果为不存在的模板请求url,则会抛出一个错误,说明它无法呈现该模板,这是有意义的,因为它不存在。但是,如果模板不存在,我希望能够显示404未找到页面。有可能这样做吗?或者有没有人有更好的方法让您可以在不必向
Catalyst
应用程序添加空操作的情况下拥有模板页面?我知道可以使用perl的文件测试来查看文件系统中是否存在模板,但是有更好的方法吗?谢谢

更新

这就是我当前的包装器的外观:

[% 
    debug("Applying HTML page layout wrappers to $template.name\n");
    content WRAPPER "$host/site/html" + "$host/site/layout";
-%]
这主要是由TTSite生成的。我是否可以做一些类似于RET建议的事情,如果失败,我可以使用try-catch块来使用404页面

更新

我已尝试将包装器模板更新为:

[%- 
    TRY;
        content WRAPPER "$host/site/html" + "$host/site/layout"; 
    CATCH file;
        "File Error! $error.info";
    CATCH;
        "Error: $error.info!";
    END;
-%]
当它找不到页面时,它会说有一个文件错误:

Couldn't render template test.html: file error - test.html: not found
然而,它不会去我的任何一个捕获块。我应该把它放在别的地方吗

更新

文件上说:

Note that the DEFAULT option (disabled by default) allows you to specify a default 
file to be used any time a template file can't be found. This will prevent file 
exceptions from ever being raised when a non-existant file is requested (unless,
of course, the DEFAULT file your specify doesn't exist). Errors encountered once 
the file has been found (i.e. read error, parse error) will be raised as file 
exceptions as per usual.

这正是我想要的,但是没有关于如何使用它的例子。有人知道如何使用默认选项吗?

对于静态内容,您可能根本不需要使用Catalyst。通常,静态内容(如图像、CSS、Javascript)由web服务器(nginx或APache)直接提供。您可以对HTML静态文件执行相同的操作


如果您真的想混合静态和动态内容,请查看Catalyst::Plugin::static::Simple]和
$c->SERVICE\u static\u file($file\u path)
函数。

我对Julien的答案投了赞成票,因为他完全正确-这是处理真正静态资源的最佳方式。如果只是HTML,让他们将其放在静态区域,并根据需要为web服务器设置别名或位置记录

但是,如果您的设计人员正在生成需要放入
包装器中的模板,或者需要一些动态处理,那么这种方法很快就会遇到一些限制

您可以执行以下操作,而不是像那样直接处理模板:

sub any_template :Regex('(.+)\.html$') { 
    my ($self, $c) = @_; 
    $c->stash(
        template => $c->action . '.html',
    );
}
==Root.pm===

sub any_template {
    ...
    $c->stash(template => 'static.tt');
}
[%- WRAPPER foo.tt -%]
[%- SET tmpl = c.action;
    TRY;
        # use either PROCESS if a template, or INCLUDE if it's HTML
        PROCESS tmpl _ ".tt";
        # INCLUDE tmpl _ ".html"; # or this
    CATCH;
        PROCESS "404.tt";
    END -%]
[%- END -%]
==static.tt===

sub any_template {
    ...
    $c->stash(template => 'static.tt');
}
[%- WRAPPER foo.tt -%]
[%- SET tmpl = c.action;
    TRY;
        # use either PROCESS if a template, or INCLUDE if it's HTML
        PROCESS tmpl _ ".tt";
        # INCLUDE tmpl _ ".html"; # or this
    CATCH;
        PROCESS "404.tt";
    END -%]
[%- END -%]

因此,找不到的文件将被优雅地处理。使用
404.tt
模板意味着您的包装器的页眉/页脚等仍然存在。

因此我最终找到了一个解决方案,让我可以做我想做的事情。我没有使用默认的RenderView,而是创建了自己的:

#old end action
#sub end : ActionClass('RenderView') {}

sub end : Private { 
    my ($self, $c) = @_; 

    return if $c->res->body ne '';  

    my $output;
    eval { $output = $c->view($c->stash->{current_view})->render($c,$c->stash->{template})};

    unless($@) { 
        $c->res->body($output);
    }   
    else {
        $c->res->status(404);
        $c->stash->{template} = 'errors/404.html';
        $c->forward($c->view('NO_HTML'));
    }   
}

它可能有点黑客,但它做了我想要的,允许我在找不到页面时显示404页面和404响应,这允许我保持灵活性,不必为我创建的每个模板定义操作。

但是我失去了使用模板系统的好处,其中唯一需要更改的内容是在页面的中间。我希望我的设计师不必到处重复相同的页眉、页脚等。因此,它是“静态”内容,但实际上我仍然希望获得模板系统(如模板工具包)的好处。我是否可以在没有相同页眉和页脚的情况下显示
404.tt
?我已经更新了上面的帖子,显示了我当前的包装器代码。如果出现错误,我有没有办法像您在示例中所做的那样处理404.tt?您不能将此逻辑放入包装器中,因为
内容
首先生成,然后生成包装器-它是由内而外设计的。因此,失败的模板渲染已经发生。在回答关于在404上更改页眉/页脚的问题时,只需在404.tt内设置一个变量,并在包装器中对其进行测试。或者在
CATCH
块中放置不同的
包装器。