Как я могу применить файл CSS к определенному шаблону в моем веб-приложении Catalyst с помощью оболочки - PullRequest
0 голосов
/ 03 июля 2018

Я не очень понимаю, как работает оболочка. Я понял пример руководства по катализатору, но не знаю, как применить конкретный файл CSS для определенного шаблона. Должен ли я использовать инструкцию [% IF%] в моем wrapper.tt для выбора определенного шаблона? Должен ли я вызывать файл CSS с помощью stash, как для шаблона в контроллере?

Несколько примеров или подсказок было бы здорово, спасибо

1 Ответ

0 голосов
/ 03 июля 2018

Вы, безусловно, можете назначить файл 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 в вашем приложении я считаю, что было бы разумнее объединить все стили в один файл и минимизировать его. В любом случае, ваши пользователи будут загружать большинство из них, поэтому зачем загружать несколько файлов и загружать каждую начальную страницу немного медленнее, а кэш-память взорвать, если вы можете просто загрузить самую первую страницу немного дольше а потом все читать из кеша?

...