Вы, безусловно, можете назначить файл CSS для переменной stash в вашем контроллере.
sub frobnicate :Local {
my ($self, $c) = @_;
# ...
# this would probably be implied, i.e. in a properly configured Catalyst
# you don't have to actually set this, it will just load the right thing
$c->stash->{template} = 'frobnicate';
# this one is for loading the right CSS
$c->stash->{css_file} = 'frobnication.css';
}
А затем в вашей оболочке TT, возможно, завернутой в [% IF css_file %]...[% END %]
:
<head>
<link rel="stylesheet" href="[% css_file %]">
</head>
Это бы сработало, но это не очень хорошая практика, потому что вы нарушаете разделение интересов . Внешний вид страницы не должен иметь ничего общего с вашим контроллером приложений.
Вы также можете просто загружать каждый файл CSS в любое время, когда это необходимо, но это тоже плохая практика, потому что это повлияет на время загрузки страницы и порядок загрузки. Как правило, CSS ставится наверху в <head>
, а большинство javascript-файлов - в конце страницы, прямо перед </body>
, так что уже есть контент, отображаемый до того, как браузер отключится и получит и запустит javascript.
Более гибким, но и более сложным решением является написание метода в вашем представлении, который можно представить как метод TT, в Template Toolkit и использование его для добавления CSS-файлов в хранилище при необходимости. Вы можете сделать это с помощью expose_methods
.
package MyApp::View::TT; # or whatever you have called this
# ...
expose_methods => [qw/add_css_file/],
# ...
sub add_css_file {
my ( $c, $self, $css_file ) = @_;
push @{ $c->stash->{_css_files} }, $css_file;
return;
}
Теперь вы можете использовать это в файлах вашего шаблона. У вас может быть блок в самом верху или в самом низу каждого файла, чтобы добавлять CSS-файлы в список файлов, которые должны быть загружены в том месте, где они логически принадлежат.
<h1>Order Confirmation</h1>
[% add_css_file('confirmation.css') %]
В вашей оболочке вы можете перебирать этот список файлов и загружать каждый из них. Как вы можете видеть, этот подход дает вам преимущество в том, что вы можете иметь более одного файла.
<head>
[% FOREACH file IN _css_files %]
<link rel="stylesheet" href="[% file %]">
[% END %]
</head>
Они будут доступны в тайнике, потому что оболочка обрабатывается после внутренней части страницы, но вы не можете сделать это непосредственно из шаблона, потому что вы не можете изменить тайник в Template Toolkit. Если нет файлов, это ничего не сделает, потому что циклу нечего повторять.
Обратите внимание, как я назвал ключ от тайника _css_file
. Подчеркивание _
указывает, что это частная переменная. Perl не имеет понятия приватного или публичного, но это соглашение, которое запрещает другим разработчикам возиться с этим.
Было бы целесообразно добавить второй метод в представление, чтобы прочитать список и вернуть его. Это отделило бы детали реализации того, как список файлов полностью хранится в шаблоне. Вы можете изменить это полностью, не касаясь файлов шаблона вообще.
Если у вас есть этот открытый метод, было бы разумно, например, убедиться, что каждый файл включен только один раз, например с List::Util::uniq
или с использованием хеша и доступа к key
s вместо перехода к массиву.
Первоначально я использовал этот подход для файлов JavaScript, а не для CSS. Для CSS в вашем приложении я считаю, что было бы разумнее объединить все стили в один файл и минимизировать его. В любом случае, ваши пользователи будут загружать большинство из них, поэтому зачем загружать несколько файлов и загружать каждую начальную страницу немного медленнее, а кэш-память взорвать, если вы можете просто загрузить самую первую страницу немного дольше а потом все читать из кеша?