1

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

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

这使得任何以“.html”结尾的请求都将查找该名称的模板。但是,如果为不存在的模板请求 url,则Template Toolkit会抛出一个错误,指出它无法呈现该模板,这是有道理的,因为它不存在。但是,如果模板不存在,我希望能够显示我的 404 not found 页面。是否有可能做到这一点?或者有没有人有更好的方法让你可以拥有模板页面,而不必向你的Catalyst应用程序添加一个空操作?我知道可以使用 perl 的-e文件测试来查看文件系统上是否存在模板,但是有没有更好的方法呢?谢谢!

更新

这是我当前的包装器的样子:

[% 
    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

但是,它不会进入我的任何一个 catch 块。我应该把它放在别的地方吗?

更新

模板工具包文档说:

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.

这正是我正在寻找的,但没有如何使用它的示例。有谁知道如何使用该DEFAULT选项?

4

3 回答 3

1

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

但是,如果您的设计师正在制作需要放入 aWRAPPER或需要一些动态处理的模板,那么您将很快遇到这种方法的一些限制。

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

=== 根.pm ===

sub any_template {
    ...
    $c->stash(template => 'static.tt');
}

=== 静态.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模板意味着您的包装器的页眉/页脚等仍然存在。

于 2013-05-23T01:00:52.613 回答
1

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

如果您真的想混合静态和动态内容,请查看 Catalyst::Plugin::Static::Simple] 1$c->serve_static_file($file_path)函数。

于 2013-05-22T20:58:33.603 回答
0

所以我最终找到了一个解决方案,让我可以做我想做的事。我没有使用默认的 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'));
    }   
}

它可能有点 hacky,但它可以满足我的要求,并允许我在找不到页面时显示 404 页面以及 404 响应,这使我能够保持不必定义动作的灵活性对于我创建的每个模板。

于 2013-05-24T23:11:00.703 回答