Spec-Zone.ru › Ruby on Rails 8.1

class ActionView::Template

Родительский класс:
Object

Шаблон Action View

Константы

NONE
STRICT_LOCALS_REGEX

Атрибуты

format [R]
frozen_string_literal [RW]
handler [R]
identifier [R]
variable [R]
variant [R]
virtual_path [R]

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

mime_types_implementation= (implementation) Показать исходный код
# File actionview/lib/action_view/template.rb, line 184
def mime_types_implementation=(implementation)
  # This method isn't thread-safe, but it's not supposed
  # to be called after initialization
  if self::Types != implementation
    remove_const(:Types)
    const_set(:Types, implementation)
  end
end
new (source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil) Показать исходный код
# File actionview/lib/action_view/template.rb, line 199
def initialize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
  @source            = source.dup
  @identifier        = identifier
  @handler           = handler
  @compiled          = false
  @locals            = locals
  @virtual_path      = virtual_path

  @variable = if @virtual_path
    base = @virtual_path.end_with?("/") ? "" : ::File.basename(@virtual_path)
    base =~ /\A_?(.*?)(?:\.\w+)*\z/
    $1.to_sym
  end

  @format            = format
  @variant           = variant
  @compile_mutex     = Mutex.new
  @strict_locals     = NONE
  @strict_local_keys = nil
  @type              = nil
end

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

encode! () Показать исходный код
# File actionview/lib/action_view/template.rb, line 321
def encode!
  source = self.source

  return source unless source.encoding == Encoding::BINARY

  # Look for # encoding: *. If we find one, we'll encode the
  # String in that encoding, otherwise, we'll use the
  # default external encoding.
  if source.sub!(LEADING_ENCODING_REGEXP, "")
    encoding = magic_encoding = $1
  else
    encoding = Encoding.default_external
  end

  # Tag the source with the default external encoding
  # or the encoding specified in the file
  source.force_encoding(encoding)

  # If the user didn't specify an encoding, and the handler
  # handles encodings, we simply pass the String as is to
  # the handler (with the default_external tag)
  if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding?
    source
  # Otherwise, if the String is valid in the encoding,
  # encode immediately to default_internal. This means
  # that if a handler doesn't handle encodings, it will
  # always get Strings in the default_internal
  elsif source.valid_encoding?
    source.encode!
  # Otherwise, since the String is invalid in the encoding
  # specified, raise an exception
  else
    raise WrongEncodingError.new(source, encoding)
  end
end

Этот метод отвечает за правильную установку кодировки исходного текста. До этого момента мы считаем, что исходный текст представляет собой двоичные данные. Если дополнительные сведения не указаны, мы предполагаем, что кодировка совпадает с Encoding.default_external.

Пользователь также может указать кодировку с помощью комментария в первой строке шаблона (# encoding: NAME-OF-ENCODING). Это работает с любым движком шаблонов: перед передачей исходного текста движку мы удаляем комментарий с указанием кодировки, оставляя вместо него пустую строку.

inspect () Показать исходный код
# File actionview/lib/action_view/template.rb, line 300
def inspect
  "#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>"
end
local_assigns () Показать исходный код
# File actionview/lib/action_view/template.rb, line 165
eager_autoload do
  autoload :Error
  autoload :RawFile
  autoload :Renderable
  autoload :Handlers
  autoload :HTML
  autoload :Inline
  autoload :Types
  autoload :Sources
  autoload :Text
  autoload :Types
end

Возвращает хеш с определёнными локальными переменными.

Для следующего рендеринга подшаблона:

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

В подшаблонах можно использовать local_assigns, чтобы получить доступ к локальным переменным:

local_assigns[:headline] # => "Welcome"

Каждый ключ в local_assigns доступен как локальная переменная партиала:

local_assigns[:headline] # => "Welcome"
headline                 # => "Welcome"

Поскольку local_assigns — это Hash, он совместим с оператором сопоставления с образцом при присваивании, появившимся в Ruby 3.1:

local_assigns => { headline:, **options }
headline                 # => "Welcome"
options                  # => {}

Сопоставление с образцом при присваивании также поддерживает переименование переменных:

local_assigns => { headline: title }
title                    # => "Welcome"

Если шаблон обращается к переменной, которая не была передана в представление в составе locals: { ... } Hash, шаблон вызовет исключение ActionView::Template::Error:

<%# => raises ActionView::Template::Error %>
<% alerts.each do |alert| %>
  <p><%= alert %></p>
<% end %>

Поскольку local_assigns возвращает экземпляр Hash, можно условно прочитать переменную, а затем использовать значение по умолчанию, если ключ не входит в параметры locals: { ... }:

<% local_assigns.fetch(:alerts, []).each do |alert| %>
  <p><%= alert %></p>
<% end %>

Сочетание сопоставления с образцом при присваивании из Ruby 3.1 и вызовов +Hash#with_defaults+ позволяет компактно присваивать локальные переменные партиала:

<% local_assigns.with_defaults(alerts: []) => { headline:, alerts: } %>

<h1><%= headline %></h1>

<% alerts.each do |alert| %>
  <p><%= alert %></p>
<% end %>

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

<%# locals: (headline:, alerts: []) %>

<h1><%= headline %></h1>

<% alerts.each do |alert| %>
  <p><%= alert %></p>
<% end %>

Подробнее о строгих локальных переменных см. в руководстве Обзор Action View.

locals () Показать исходный код
# File actionview/lib/action_view/template.rb, line 223
def locals
  if strict_locals?
    nil
  else
    @locals
  end
end

Локальные переменные, для которых этот шаблон был или будет скомпилирован, либо nil, если это шаблон со строгими локальными переменными.

render (view, locals, buffer = nil, implicit_locals: [], add_to_stack: true, &block) Показать исходный код
# File actionview/lib/action_view/template.rb, line 271
def render(view, locals, buffer = nil, implicit_locals: [], add_to_stack: true, &block)
  instrument_render_template do
    compile!(view)

    if strict_locals? && @strict_local_keys && !implicit_locals.empty?
      locals_to_ignore = implicit_locals - @strict_local_keys
      locals.except!(*locals_to_ignore)
    end

    if buffer
      view._run(method_name, self, locals, buffer, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)
      nil
    else
      result = view._run(method_name, self, locals, OutputBuffer.new, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)
      result.is_a?(OutputBuffer) ? result.to_s : result
    end
  end
rescue => e
  handle_render_error(view, e)
end

Рендерит шаблон. Если шаблон ещё не скомпилирован, компиляция выполняется непосредственно перед рендерингом.

Для этого метода включена инструментация «!render_template.action_view». Обратите внимание: в названии инструментации используется восклицательный знак, потому что в рабочей среде её не следует использовать. Она замедляет работу только в том случае, если на неё подписан слушатель.

short_identifier () Показать исходный код
# File actionview/lib/action_view/template.rb, line 296
def short_identifier
  @short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
end
source () Показать исходный код
# File actionview/lib/action_view/template.rb, line 304
def source
  @source.to_s
end
strict_locals! () Показать исходный код
# File actionview/lib/action_view/template.rb, line 366
def strict_locals!
  if @strict_locals == NONE
    self.source.sub!(STRICT_LOCALS_REGEX, "")
    @strict_locals = $1&.rstrip

    return if @strict_locals.nil? # Magic comment not found

    @strict_locals = "**nil" if @strict_locals.blank?
  end

  @strict_locals
end

Этот метод помечает шаблон как использующий строгие локальные переменные. Это означает, что шаблон может принимать только локальные переменные, определённые в магическом комментарии. Например, если шаблон принимает локальные переменные title и comment_count, добавьте в файл шаблона следующее:

<%# locals: (title: "Default title", comment_count: 0) %>

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

strict_locals? () Показать исходный код
# File actionview/lib/action_view/template.rb, line 380
def strict_locals?
  strict_locals!
end

Возвращает, использует ли шаблон строгие локальные переменные.

supports_streaming? () Показать исходный код
# File actionview/lib/action_view/template.rb, line 261
def supports_streaming?
  handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
end

Возвращает, поддерживает ли базовый обработчик потоковую передачу. Если да, при начале рендеринга может быть передан буфер потоковой передачи.

translate_location (backtrace_location, spot) Показать исходный код
# File actionview/lib/action_view/template.rb, line 251
def translate_location(backtrace_location, spot)
  if handler.respond_to?(:translate_location)
    handler.translate_location(spot, backtrace_location, encode!) || spot
  else
    spot
  end
end

Преобразует местоположение ошибки, возвращённое ErrorHighlight, в соответствующее местоположение в исходном коде шаблона.

type () Показать исходный код
# File actionview/lib/action_view/template.rb, line 292
def type
  @type ||= Types[format]
end

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

instrument (action, &block) Показать исходный код
# File actionview/lib/action_view/template.rb, line 578
def instrument(action, &block) # :doc:
  ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block)
end

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

Spec-Zone.ru

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