Spec-Zone.ru › Ruby on Rails 7.2

класс ActionView::Template

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

Шаблон 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 185
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 200
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 312
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

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

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

inspect() Показать исходный код
# File actionview/lib/action_view/template.rb, line 291
def inspect
  "#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>"
end
local_assigns() Показать исходный код
# File actionview/lib/action_view/template.rb, line 166
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 224
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 262
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 287
def short_identifier
  @short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
end
source() Показать исходный код
# File actionview/lib/action_view/template.rb, line 295
def source
  @source.to_s
end
strict_locals!() Показать исходный код
# File actionview/lib/action_view/template.rb, line 357
def strict_locals!
  if @strict_locals == NONE
    self.source.sub!(STRICT_LOCALS_REGEX, "")
    @strict_locals = $1

    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 371
def strict_locals?
  strict_locals!
end

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

supports_streaming?() Показать исходный код
# File actionview/lib/action_view/template.rb, line 252
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 242
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 283
def type
  @type ||= Types[format]
end

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

instrument(action, &block) Показать исходный код
# File actionview/lib/action_view/template.rb, line 569
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