Undr

На память

Записи с меткой ‘templates’

Кэширование фрагментов HTML кода в шаблонах ActionMailer

without comments

1 Star2 Stars3 Stars4 Stars5 Stars (1 голосов, средний: 5.00 из 5)
Loading ... Loading ...

Задача: реализовать кэширование фрагментов 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 не содержит методы для кэширования. И в результате у нас ошибка:

Error: ActionView::Template::Error - undefined method `perform_caching' for #<SomeMailer:0x0000010827a9f8>
  /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 кода в результате, нужно написать примерно такой хелпер:

def mailer_cache key, &block
  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 %>
...

Написал undr ()

28 июня 2011 в 14:58

Избавляемся от операторов if и foreach в шаблонах

without comments

1 Star2 Stars3 Stars4 Stars5 Stars (Еще не оценили)
Loading ... Loading ...

Часто в шаблонах приходится использовать вывод по условию. В результате шаблон обрастает трудно читаемыми конструкциями, типа:

< ? if(isset($comments)): ?>
< ? foreach($comments as $comment): ?>
< ?= include_view("comment", array("comment" => $comment)) ?>
< ? endforeach ?>
< ? endif ?>
< ? if($reader->canWriteComments()): ?>
< ?= include_view("comment_form") ?>
< ? endif ?>

или

<div <? if($page->isActive()):?> class="active"< ? endif ?></div>

Можно написать помощника, который будет выводить текст по условию.

Читать далее »

Написал undr ()

8 сентября 2009 в 19:52