module ActionView
# nodoc:
# = Action View Base
#
# Action View templates can be written in several ways.
# If the template file has a .erb extension, then it uses the erubi[https://rubygems.org/gems/erubi]
# template system which can embed Ruby into an HTML document.
# If the template file has a .builder extension, then Jim Weirich's Builder::XmlMarkup library is used.
#
# == ERB
#
# You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
# following loop for names:
#
# Names of all the people
# <% @people.each do |person| %>
# Name: <%= person.name %>
# <% end %>
#
# The loop is setup in regular embedding tags <% %>, and the name is written using the output embedding tag <%= %>. Note that this
# is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
#
# <%# WRONG %>
# Hi, Mr. <% puts "Frodo" %>
#
# If you absolutely must write from within a function use +concat+.
#
# When on a line that only contains whitespaces except for the tag, <% %> suppresses leading and trailing whitespace,
# including the trailing newline. <% %> and <%- -%> are the same.
# Note however that <%= %> and <%= -%> are different: only the latter removes trailing whitespaces.
#
# === Using sub templates
#
# Using sub templates allows you to sidestep tedious replication and extract common display structures in shared templates. The
# classic example is the use of a header and footer (even though the Action Pack-way would be to use Layouts):
#
# <%= render "shared/header" %>
# Something really specific and terrific
# <%= render "shared/footer" %>
#
# As you see, we use the output embeddings for the render methods. The render call itself will just return a string holding the
# result of the rendering. The output embedding writes it to the current template.
#
# But you don't have to restrict yourself to static includes. Templates can share variables amongst themselves by using instance
# variables defined using the regular embedding tags. Like this:
#
# <% @page_title = "A Wonderful Hello" %>
# <%= render "shared/header" %>
#
# Now the header can pick up on the @page_title variable and use it for outputting a title tag:
#
#
A product of Danish Design during the Winter of '79...
#foo
"), "bar
"], "foo
<br /><p>bar</p>" # # safe_join([raw("foo
"), raw("bar
")], raw("foo
bar
" # def safe_join: (untyped array, ?untyped sep) -> untyped # Converts the array to a comma-separated sentence where the last element is # joined by the connector word. This is the html_safe-aware version of # ActiveSupport's {Array#to_sentence}[https://api.rubyonrails.org/classes/Array.html#method-i-to_sentence]. # def to_sentence: (untyped array, ?::Hash[untyped, untyped] options) -> untyped end end end module ActionView module Helpers # nodoc: # nodoc: extend ActiveSupport::Autoload def self.eager_load!: () -> untyped extend ActiveSupport::Concern include ActiveSupport::Benchmarkable include ActiveModelHelper include AssetTagHelper include AssetUrlHelper include AtomFeedHelper include CacheHelper include CaptureHelper include ControllerHelper include CspHelper include CsrfHelper include DateHelper include DebugHelper include FormHelper include FormOptionsHelper include FormTagHelper include JavaScriptHelper include NumberHelper include OutputSafetyHelper include RenderingHelper include SanitizeHelper include TagHelper include TextHelper include TranslationHelper include UrlHelper end end module ActionView module Helpers # nodoc: # = Action View Rendering # # Implements methods that allow rendering from a view context. # In order to use this module, all you need is to implement # view_renderer that returns an ActionView::Renderer object. module RenderingHelper # Returns the result of a render that's dictated by the options hash. The primary options are: # # * :partial - See ActionView::PartialRenderer. # * :file - Renders an explicit template file (this used to be the old default), add :locals to pass in those. # * :inline - Renders an inline template similar to how it's done in the controller. # * :plain - Renders the text passed in out. Setting the content # type as text/plain. # * :html - Renders the HTML safe string passed in out, otherwise # performs HTML escape on the string first. Setting the content type as # text/html. # * :body - Renders the text passed in, and inherits the content # type of text/plain from ActionDispatch::Response # object. # # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter # as the locals hash. def render: (?::Hash[untyped, untyped] options, ?::Hash[untyped, untyped] locals) { () -> untyped } -> untyped # Overwrites _layout_for in the context object so it supports the case a block is # passed to a partial. Returns the contents that are yielded to a layout, given a # name or a block. # # You can think of a layout as a method that is called with a block. If the user calls # yield :some_name, the block, by default, returns content_for(:some_name). # If the user calls simply +yield+, the default block returns content_for(:layout). # # The user can override this default by passing a block to the layout: # # # The template # <%= render layout: "my_layout" do %> # Content # <% end %> # # # The layout # # <%= yield %> # # # In this case, instead of the default block, which would return content_for(:layout), # this method returns the block that was passed in to render :layout, and the response # would be # # # Content # # # Finally, the block can take block arguments, which can be passed in by +yield+: # # # The template # <%= render layout: "my_layout" do |customer| %> # Hello <%= customer.name %> # <% end %> # # # The layout # # <%= yield Struct.new(:name).new("David") %> # # # In this case, the layout would receive the block passed into render :layout, # and the struct specified would be passed into the block as an argument. The result # would be # # # Hello David # # def _layout_for: (*untyped args) { () -> untyped } -> untyped end end end module ActionView module Helpers # = Action View Sanitize Helpers # nodoc: # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. # These helper methods extend Action View making them callable within your template files. module SanitizeHelper extend ActiveSupport::Concern # Sanitizes HTML input, stripping all but known-safe tags and attributes. # # It also strips href/src attributes with unsafe protocols like # javascript:, while also protecting against attempts to use Unicode, # ASCII, and hex character references to work around these protocol filters. # All special characters will be escaped. # # The default sanitizer is Rails::Html::SafeListSanitizer. See {Rails HTML # Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information. # # Custom sanitization rules can also be provided. # # Please note that sanitizing user-provided text does not guarantee that the # resulting markup is valid or even well-formed. # # ==== Options # # * :tags - An array of allowed tags. # * :attributes - An array of allowed attributes. # * :scrubber - A {Rails::Html scrubber}[https://github.com/rails/rails-html-sanitizer] # or {Loofah::Scrubber}[https://github.com/flavorjones/loofah] object that # defines custom sanitization rules. A custom scrubber takes precedence over # custom tags and attributes. # # ==== Examples # # Normal use: # # <%= sanitize @comment.body %> # # Providing custom lists of permitted tags and attributes: # # <%= sanitize @comment.body, tags: %w(strong em a), attributes: %w(href) %> # # Providing a custom Rails::Html scrubber: # # class CommentScrubber < Rails::Html::PermitScrubber # def initialize # super # self.tags = %w( form script comment blockquote ) # self.attributes = %w( style ) # end # # def skip_node?(node) # node.text? # end # end # # <%= sanitize @comment.body, scrubber: CommentScrubber.new %> # # See {Rails HTML Sanitizer}[https://github.com/rails/rails-html-sanitizer] for # documentation about Rails::Html scrubbers. # # Providing a custom Loofah::Scrubber: # # scrubber = Loofah::Scrubber.new do |node| # node.remove if node.name == 'script' # end # # <%= sanitize @comment.body, scrubber: scrubber %> # # See {Loofah's documentation}[https://github.com/flavorjones/loofah] for more # information about defining custom Loofah::Scrubber objects. # # To set the default allowed tags or attributes across your application: # # # In config/application.rb # config.action_view.sanitized_allowed_tags = ['strong', 'em', 'a'] # config.action_view.sanitized_allowed_attributes = ['href', 'title'] def sanitize: (untyped html, ?::Hash[untyped, untyped] options) -> untyped # Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute. def sanitize_css: (untyped style) -> untyped # Strips all HTML tags from +html+, including comments and special characters. # # strip_tags("Strip these tags!") # # => Strip these tags! # # strip_tags("Bold no more! See more here...") # # => Bold no more! See more here... # # strip_tags("Hello world!
The next great American novel starts here.
# # ==== Options # # Use symbol keyed options to add attributes to the generated tag. # # tag.section class: %w( kitties puppies ) # # => # # tag.section id: dom_id(@post) # # => # # Pass +true+ for any attributes that can render with no values, like +disabled+ and +readonly+. # # tag.input type: 'text', disabled: true # # => # # HTML5 data-* attributes can be set with a single +data+ key # pointing to a hash of sub-attributes. # # To play nicely with JavaScript conventions, sub-attributes are dasherized. # # tag.article data: { user_id: 123 } # # => # # Thus data-user-id can be accessed as dataset.userId. # # Data attribute values are encoded to JSON, with the exception of strings, symbols and # BigDecimals. # This may come in handy when using jQuery's HTML5-aware .data() # from 1.4.3. # # tag.div data: { city_state: %w( Chicago IL ) } # # => # # The generated attributes are escaped by default. This can be disabled using # +escape_attributes+. # # tag.img src: 'open & shut.png' # # =>Hello world!
# content_tag(:div, content_tag(:p, "Hello world!"), class: "strong") # # =>Hello world!
<a href=\"http://example.com/\">Example</a>
" module TextHelper extend ActiveSupport::Concern include SanitizeHelper extend ::ActionView::Helpers::SanitizeHelper::ClassMethods include TagHelper include OutputSafetyHelper # The preferred method of outputting text in your views is to use the # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods # do not operate as expected in an eRuby code block. If you absolutely must # output text within a non-output code block (i.e., <% %>), you can use the concat method. # # <% # concat "hello" # # is the equivalent of <%= "hello" %> # # if logged_in # concat "Logged in!" # else # concat link_to('login', action: :login) # end # # will either display "Logged in!" or a login link # %> def concat: (untyped string) -> untyped def safe_concat: (untyped string) -> untyped # Truncates a given +text+ after a given :length if +text+ is longer than :length # (defaults to 30). The last characters will be replaced with the :omission (defaults to "...") # for a total length not exceeding :length. # # Pass a :separator to truncate +text+ at a natural break. # # Pass a block if you want to show extra content when the text is truncated. # # The result is marked as HTML-safe, but it is escaped by default, unless :escape is # +false+. Care should be taken if +text+ contains HTML tags or entities, because truncation # may produce invalid HTML (such as unbalanced or incomplete tags). # # truncate("Once upon a time in a world far far away") # # => "Once upon a time in a world..." # # truncate("Once upon a time in a world far far away", length: 17) # # => "Once upon a ti..." # # truncate("Once upon a time in a world far far away", length: 17, separator: ' ') # # => "Once upon a..." # # truncate("And they found that many people were sleeping better.", length: 25, omission: '... (continued)') # # => "And they f... (continued)" # # truncate("Once upon a time in a world far far away
") # # => "<p>Once upon a time in a wo..." # # truncate("Once upon a time in a world far far away
", escape: false) # # => "Once upon a time in a wo..."
#
# truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
# # => "Once upon a time in a wo...Continue"
def truncate: (untyped text, ?::Hash[untyped, untyped] options) { () -> untyped } -> untyped
# Highlights one or more +phrases+ everywhere in +text+ by inserting it into
# a :highlighter string. The highlighter can be specialized by passing :highlighter
# as a single-quoted string with \1 where the phrase is to be inserted (defaults to
# '\1') or passing a block that receives each matched term. By default +text+
# is sanitized to prevent possible XSS attacks. If the input is trustworthy, passing false
# for :sanitize will turn sanitizing off.
#
# highlight('You searched for: rails', 'rails')
# # => You searched for: rails
#
# highlight('You searched for: rails', /for|rails/)
# # => You searched for: rails
#
# highlight('You searched for: ruby, rails, dhh', 'actionpack')
# # => You searched for: ruby, rails, dhh
#
# highlight('You searched for: rails', ['for', 'rails'], highlighter: '\1')
# # => You searched for: rails
#
# highlight('You searched for: rails', 'rails', highlighter: '\1')
# # => You searched for: rails
#
# highlight('You searched for: rails', 'rails') { |match| link_to(search_path(q: match, match)) }
# # => You searched for: rails
#
# highlight('ruby on rails', 'rails', sanitize: false)
# # => ruby on rails
def highlight: (untyped text, untyped phrases, ?::Hash[untyped, untyped] options) { (untyped) -> untyped } -> untyped
# Extracts an excerpt from +text+ that matches the first instance of +phrase+.
# The :radius option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
# defined in :radius (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
# then the :omission option (which defaults to "...") will be prepended/appended accordingly. Use the
# :separator option to choose the delimitation. The resulting string will be stripped in any case. If the +phrase+
# isn't found, +nil+ is returned.
#
# excerpt('This is an example', 'an', radius: 5)
# # => ...s is an exam...
#
# excerpt('This is an example', 'is', radius: 5)
# # => This is a...
#
# excerpt('This is an example', 'is')
# # => This is an example
#
# excerpt('This next thing is an example', 'ex', radius: 2)
# # => ...next...
#
# excerpt('This is also an example', 'an', radius: 8, omission: '
Here is some basic text...\n
...with a line break.
We want to put a paragraph...
\n\n...right there.
" # # simple_format("Look ma! A class!", class: 'description') # # => "Look ma! A class!
" # # simple_format("") # # => "Unblinkable.
" # # simple_format(" It's true.", {}, sanitize: false) # # => "It's true.
" def simple_format: (untyped text, ?::Hash[untyped, untyped] html_options, ?::Hash[untyped, untyped] options) -> untyped # Creates a Cycle object whose _to_s_ method cycles through elements of an # array every time it is called. This can be used for example, to alternate # classes for table rows. You can use named cycles to allow nesting in loops. # Passing a Hash as the last parameter with a :name key will create a # named cycle. The default name for a cycle without a +:name+ key is # "default". You can manually reset a cycle by calling reset_cycle # and passing the name of the cycle. The current cycle string can be obtained # anytime using the current_cycle method. # # # Alternate CSS classes for even and odd numbers... # @items = [1,2,3,4] #<%= item %> | #