класс ActionView::Template
Шаблон Action View
Константы
- NONE
- STRICT_LOCALS_REGEX
Атрибуты
Публичные методы класса
# 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 # 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 Публичные методы экземпляра
# 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). Это будет работать с любым движком шаблонов, поскольку мы обрабатываем комментарий кодировки перед передачей источника движку шаблонов, оставляя вместо него пустую строку.
# File actionview/lib/action_view/template.rb, line 291
def inspect
"#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>"
end # 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.
# File actionview/lib/action_view/template.rb, line 224
def locals
if strict_locals?
nil
else
@locals
end
end Локальные переменные, для которых был или будет скомпилирован этот шаблон, или nil, если это шаблон с жёсткими локалями.
# 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». Обратите внимание, что мы используем восклицательный знак в этой инструментации, потому что вы не хотите использовать это в производстве. Это будет медленным только в случае прослушивания.
# File actionview/lib/action_view/template.rb, line 287
def short_identifier
@short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
end # File actionview/lib/action_view/template.rb, line 295 def source @source.to_s end
# 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) %>
Строгие локальные переменные полезны для проверки аргументов шаблона и указания значений по умолчанию.
# File actionview/lib/action_view/template.rb, line 371 def strict_locals? strict_locals! end
Возвращает, использует ли шаблон строгие локальные переменные.
# File actionview/lib/action_view/template.rb, line 252 def supports_streaming? handler.respond_to?(:supports_streaming?) && handler.supports_streaming? end
Возвращает, поддерживает ли базовый обработчик потоков. Если да, при начале рендеринга может быть передан буфер потока.
# 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, в правильное местоположение источника внутри шаблона.
# File actionview/lib/action_view/template.rb, line 283 def type @type ||= Types[format] end
Приватные методы экземпляра
# 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.