1

我正在构建一个Catalyst应用程序,并且我想使用Template Toolkit作为我的模板系统。但是,我的应用程序将响应许多域,并且根据域,它会显示具有不同配置的不同内容Template Toolkit。本质上,如果我有 domain.com 和 domain2.com,我希望每个都有自己的配置。有谁知道一种优雅的方式来做到这一点,同时仍然能够使用Catalyst的视图功能?谢谢!

更新

通过将它放在根控制器中,我发现我可以在对象的配置中更改站点包装器Template Toolkit。但是,它似乎只是使用了位于其中的初始包装器lib/myapp/View/HTML.pm(我猜是因为它只是使用了初始化它的包装器)。有没有办法让它认识到我改变了这个请求的包装器?

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

    $c->view('HTML')->config->{WRAPPER} = $c->req->uri->host . '/site/wrapper';
}
4

2 回答 2

1

从历史上看,最好的想法可能是这样的:https ://metacpan.org/release/Catalyst-TraitFor-Component-ConfigPerSite ,它提供了为每个站点/主机指定配置的能力。因此,您可以指定单独的视图/包装器/数据库连接等。

于 2013-06-25T09:35:03.900 回答
1

I tend to declare WRAPPER in each main template directly, rather than globally like that.

[%- WRAPPER c.req.uri.host _ '/site/wrapper.tt'; -%]

... as I find it allows for far more flexibility.


However...

Another option that I have had great success with is using a custom template path, so that domain specific versions of your templates can over-ride defaults, where they exist. This gives you enormous flexibility to inject variations of your code as required.

=== MyApp::View::TT.pm ===

sub process {
    my ($self, $c) = @_;

    # capture original path, identify host
    my @orig_include_path = @{$self->include_path};
    my $domain = $c->req->uri->host;

    # augment every path with domain/path
    @{$self->include_path} = map { ("$domain/$_", $_) } @orig_include_path;

    $self->SUPER::process($c);

    # revert path
    @{$self->include_path} = @orig_include_path;
}

The net result of which is that every call for a WRAPPER, a PROCESS or an INCLUDE will check for a domain specific version or produce the generic version, i.e.

[%- WRAPPER wrapper.tt -%]

will find $domain/wrapper.tt or fall back to wrapper.tt if there's no such file. This automatically extends to:

  • foo/bar/baz.tt
  • domain1/foo/bar/baz.tt
  • domain2/foo/bar/baz.tt

Hope that's useful.

于 2013-05-16T02:30:20.920 回答