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: # = 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 %> | #