ActionView::Template (original) (raw)

Action View Template

Namespace

Methods

E

I

L

M

N

R

S

T

Constants

NONE = Object.new
STRICT_LOCALS_REGEX = /\#\s+locals:\s+\((.*)\)/

Attributes

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

Class Public methods

Source: show | on GitHub

def mime_types_implementation=(implementation)

if self::Types != implementation remove_const(:Types) const_set(:Types, implementation) end end

Source: show | on GitHub

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

Instance Public methods

This method is responsible for properly setting the encoding of the source. Until this point, we assume that the source is BINARY data. If no additional information is supplied, we assume the encoding is the same as Encoding.default_external.

The user can also specify the encoding via a comment on the first line of the template (# encoding: NAME-OF-ENCODING). This will work with any template engine, as we process out the encoding comment before passing the source on to the template engine, leaving a blank line in its stead.

Source: show | on GitHub

def encode! source = self.source

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

if source.sub!(LEADING_ENCODING_REGEXP, "") encoding = magic_encoding = $1 else encoding = Encoding.default_external end

source.force_encoding(encoding)

if !magic_encoding && @handler.respond_to?(:handles_encoding?) && @handler.handles_encoding? source

elsif source.valid_encoding? source.encode!

else raise WrongEncodingError.new(source, encoding) end end

Source: show | on GitHub

def inspect "#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>" end

Returns a hash with the defined local variables.

Given this sub template rendering:

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

You can use local_assigns in the sub templates to access the local variables:

local_assigns[:headline] # => "Welcome"

Each key in local_assigns is available as a partial-local variable:

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

Since local_assigns is a Hash, it’s compatible with Ruby 3.1’s pattern matching assignment operator:

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

Pattern matching assignment also supports variable renaming:

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

If a template refers to a variable that isn’t passed into the view as part of the locals: { ... } Hash, the template will raise an ActionView::Template::Error:

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

Since local_assigns returns a Hash instance, you can conditionally read a variable, then fall back to a default value when the key isn’t part of the locals: { ... } options:

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

Combining Ruby 3.1’s pattern matching assignment with calls to +Hash#with_defaults+ enables compact partial-local variable assignments:

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

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

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

By default, templates will accept any locals as keyword arguments and make them available to local_assigns. To restrict what local_assigns a template will accept, add a locals: magic comment:

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

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

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

Read more about strict locals in Action View Overview in the guides.

Source: show | on GitHub

eager_autoload do autoload :Error autoload :RawFile autoload :Renderable autoload :Handlers autoload :HTML autoload :Inline autoload :Types autoload :Sources autoload :Text autoload :Types end

The locals this template has been or will be compiled for, or nil if this is a strict locals template.

Source: show | on GitHub

def locals if strict_locals? nil else @locals end end

Render a template. If the template was not compiled yet, it is done exactly before rendering.

This method is instrumented as “!render_template.action_view”. Notice that we use a bang in this instrumentation because you don’t want to consume this in production. This is only slow if it’s being listened to.

Source: show | on GitHub

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

Source: show | on GitHub

def short_identifier @short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier end

This method is responsible for marking a template as having strict locals which means the template can only accept the locals defined in a magic comment. For example, if your template accepts the locals title and comment_count, add the following to your template file:

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

Strict locals are useful for validating template arguments and for specifying defaults.

Source: show | on GitHub

def strict_locals! if @strict_locals == NONE self.source.sub!(STRICT_LOCALS_REGEX, "") @strict_locals = $1

return if @strict_locals.nil? 

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

end

@strict_locals end

Returns whether a template is using strict locals.

Returns whether the underlying handler supports streaming. If so, a streaming buffer may be passed when it starts rendering.

Source: show | on GitHub

def supports_streaming? handler.respond_to?(:supports_streaming?) && handler.supports_streaming? end

Translate an error location returned by ErrorHighlight to the correct source location inside the template.

Source: show | on GitHub

def translate_location(backtrace_location, spot) if handler.respond_to?(:translate_location) handler.translate_location(spot, backtrace_location, encode!) || spot else spot end end

Instance Private methods

Source: show | on GitHub

def instrument(action, &block) ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block) end