Записи с меткой ‘templates’
Кэширование фрагментов HTML кода в шаблонах ActionMailer
Задача: реализовать кэширование фрагментов HTML кода в шаблоне письма для рассылки.
Первое решение которое приходит в голову – это использовать хелпер cache, например так:
<h1>Result has been executed for long time</h1>
<% cache cache_key do %>
<div>
<%= doing_something_long_time_and_show_result %>
</div>
<% end %>
...
Но этот способ не работает, так как ActiveMailer не содержит методы для кэширования. И в результате у нас ошибка:
/Users/undr/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.0.7/lib/action_view/helpers/cache_helper.rb:37:in `cache'
...
Второй вариант, это использовать Rails.cache.fetch:
<h1>Result has been executed for long time</h1>
<%= Rails.cache.fetch cache_key do %>
<div>
<%= doing_something_long_time_and_show_result %>
</div>
<% end %>
...
Ошибки уже нет, но результат не верный. В кэш попадает все содержимое шаблона, а не часть в блоке, и, как следствие, в результате письмо содержит дублированные куски HTML кода. То есть сначала выводится заголовок, потом опять заголовок и содержимое блока.
Чтобы убрать дублирование HTML кода в результате, нужно написать примерно такой хелпер:
Rails.cache.fetch(key) do
with_output_buffer(&block)
end
end
И в шаблоне вызывать его.
<h1>Result has been executed for long time</h1>
<%= mailer_cache cache_key do %>
<div>
<%= doing_something_long_time_and_show_result %>
</div>
<% end %>
...
Избавляемся от операторов if и foreach в шаблонах
Часто в шаблонах приходится использовать вывод по условию. В результате шаблон обрастает трудно читаемыми конструкциями, типа:
< ? foreach($comments as $comment): ?>
< ?= include_view("comment", array("comment" => $comment)) ?>
< ? endforeach ?>
< ? endif ?>
< ? if($reader->canWriteComments()): ?>
< ?= include_view("comment_form") ?>
< ? endif ?>
или
Можно написать помощника, который будет выводить текст по условию.

