Spec-Zone.ru › Ruby on Rails 7.2

класс ActionView::Base

Родитель:
Объект

Шаблон Action View

Шаблоны Action View могут быть написаны различными способами. Если файл шаблона имеет расширение .erb, то он использует систему шаблонов erubi, которая позволяет встраивать Ruby-код в HTML-документ. Если файл шаблона имеет расширение .builder, то используется библиотека Builder::XmlMarkup от Джима Вайрича.

Вы вызываете ERB с помощью встроек, таких как <% %>, <% -%>, и <%= %>. Тег <%= %> используется, когда нужно вывести результат. Рассмотрим следующий цикл для имён:

<b>Names of all the people</b>
<% @people.each do |person| %>
  Name: <%= person.name %><br/>
<% end %>

Цикл задаётся с помощью обычных встроек <% %>, а имя выводится с помощью тега вывода <%= %>. Обратите внимание, что это не просто рекомендация по использованию. Обычные функции вывода, такие как print или puts, не будут работать с шаблонами ERB. Поэтому следующий код будет неправильным:

<%# WRONG %>
Hi, Mr. <% puts "Frodo" %>

Если вам абсолютно необходимо выполнить вывод из функции, используйте concat.

Когда на строке содержится только пробелы, кроме тега, <% %> подавляет ведущие и хвостовые пробелы, включая конечную новую строку. <% %> и <%- -%> эквивалентны. Однако обратите внимание, что <%= %> и <%= -%> отличаются: только последний удаляет хвостовые пробелы.

Использование подшаблонов

Использование подшаблонов позволяет избежать излишней повторяемости и извлечь общие структуры отображения в общих шаблонах. Классический пример — использование заголовка и подвала (хотя для Action Pack лучше использовать Layouts):

<%= render "application/header" %>
Something really specific and terrific
<%= render "application/footer" %>

Как видите, мы используем теги вывода для методов render. Сам вызов render вернёт строку, содержащую результат рендеринга. Тег вывода запишет его в текущий шаблон.

Но вы не ограничены статическими включениями. Шаблоны могут обмениваться переменными, используя экземпляры переменных, определённые с помощью обычных встроек. Например:

<% @page_title = "A Wonderful Hello" %>
<%= render "application/header" %>

Теперь заголовок может получить доступ к переменной @page_title и использовать её для вывода тега заголовка:

<title><%= @page_title %></title>

Передача локальных переменных подшаблонам

Вы можете передавать локальные переменные подшаблонам, используя хэш, где ключами являются имена переменных, а значениями — объекты:

<%= render "application/header", { headline: "Welcome", person: person } %>

Теперь к ним можно получить доступ в application/header с помощью:

Headline: <%= headline %>
First name: <%= person.first_name %>

Локальные переменные, переданные подшаблонам, доступны как хэш local_assigns. Это позволяет получить доступ к переменным следующим образом:

Headline: <%= local_assigns[:headline] %>

Это полезно в тех случаях, когда вы не уверены, была ли присвоена локальная переменная. Кроме того, можно использовать defined? headline для проверки присвоения переменной перед её использованием.

По умолчанию шаблоны принимают любые locals в качестве ключевых аргументов. Чтобы ограничить, какие locals шаблон принимает, добавьте locals: магический комментарий:

<%# locals: (headline:) %>

Headline: <%= headline %>

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

<%# locals: (headline: nil) %>

<% unless headline.nil? %>
Headline: <%= headline %>
<% end %>

Дополнительную информацию о строгих локальных переменных можно найти в Обзоре Action View в руководстве.

Template кэширование

По умолчанию Rails компилирует каждый шаблон в метод для его рендеринга. При изменении шаблона Rails проверяет время изменения файла и повторно компилирует его в режиме разработки.

Библиотека Builder

Шаблоны Builder — это более программный способ по сравнению с ERB. Они особенно полезны для генерации XML-контента. Объект XmlMarkup с именем xml автоматически становится доступным для шаблонов с расширением .builder.

Вот несколько основных примеров:

xml.em("emphasized")                                 # => <em>emphasized</em>
xml.em { xml.b("emph & bold") }                      # => <em><b>emph &amp; bold</b></em>
xml.a("A Link", "href" => "http://onestepback.org")  # => <a href="http://onestepback.org">A Link</a>
xml.target("name" => "compile", "option" => "fast")  # => <target option="fast" name="compile"\>
                                                     # NOTE: order of attributes is not specified.

Любой метод с блоком будет обрабатываться как XML-тег с вложенным контентом в блоке. Например, следующий код:

xml.div do
  xml.h1(@person.name)
  xml.p(@person.bio)
end

сгенерирует что-то вроде:

<div>
  <h1>David Heinemeier Hansson</h1>
  <p>A product of Danish Design during the Winter of '79...</p>
</div>

Вот полный пример RSS, используемый в Basecamp:

xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
  xml.channel do
    xml.title(@feed_title)
    xml.link(@url)
    xml.description "Basecamp: Recent items"
    xml.language "en-us"
    xml.ttl "40"

    @recent_items.each do |item|
      xml.item do
        xml.title(item_title(item))
        xml.description(item_description(item)) if item_description(item)
        xml.pubDate(item_pubDate(item))
        xml.guid(@person.firm.account.url + @recent_items.url(item))
        xml.link(@person.firm.account.url + @recent_items.url(item))

        xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
      end
    end
  end
end

Дополнительную информацию о Builder можно найти в исходном коде.

Атрибуты

lookup_context[Ч]
view_renderer[Ч]

Публичные методы класса

cache_template_loading() Показать исходный код
# File actionview/lib/action_view/base.rb, line 187
def cache_template_loading
  ActionView::Resolver.caching?
end
cache_template_loading=(value) Показать исходный код
# File actionview/lib/action_view/base.rb, line 191
def cache_template_loading=(value)
  ActionView::Resolver.caching = value
end
inspect() Показать исходный код
# File actionview/lib/action_view/base.rb, line 207
def inspect
  "#<ActionView::Base:#{'%#016x' % (object_id << 1)}>"
end

Публичные методы экземпляра

_run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block) Показать исходный код
# File actionview/lib/action_view/base.rb, line 261
def _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block)
  _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template
  @current_template = template if add_to_stack
  @output_buffer = buffer

  if has_strict_locals
    begin
      public_send(method, locals, buffer, **locals, &block)
    rescue ArgumentError => argument_error
      raise(
        ArgumentError,
        argument_error.
          message.
            gsub("unknown keyword:", "unknown local:").
            gsub("missing keyword:", "missing local:").
            gsub("no keywords accepted", "no locals accepted").
            concat(" for #{@current_template.short_identifier}")
      )
    end
  else
    public_send(method, locals, buffer, &block)
  end
ensure
  @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template
end
compiled_method_container() Показать исходный код
# File actionview/lib/action_view/base.rb, line 287
    def compiled_method_container
      raise NotImplementedError, <<~msg.squish
        Subclasses of ActionView::Base must implement `compiled_method_container`
        or use the class method `with_empty_template_cache` for constructing
        an ActionView::Base subclass that has an empty cache.
      msg
    end
in_rendering_context(options) { |view_renderer| ... } Показать исходный код
# File actionview/lib/action_view/base.rb, line 295
def in_rendering_context(options)
  old_view_renderer  = @view_renderer
  old_lookup_context = @lookup_context

  if !lookup_context.html_fallback_for_js && options[:formats]
    formats = Array(options[:formats])
    if formats == [:js]
      formats << :html
    end
    @lookup_context = lookup_context.with_prepended_formats(formats)
    @view_renderer = ActionView::Renderer.new @lookup_context
  end

  yield @view_renderer
ensure
  @view_renderer = old_view_renderer
  @lookup_context = old_lookup_context
end

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API