Module: Hanami::View::Helpers::TagHelper

Extended by:
TagHelper
Included in:
TagHelper
Defined in:
lib/hanami/view/helpers/tag_helper.rb,
lib/hanami/view/helpers/tag_helper/tag_builder.rb

Overview

Helper methods for generating HTML tags.

When using full Hanami apps, these helpers will be automatically available in your view templates, part classes and scope classes.

When using hanami-view standalone, include this module directly in your base part and scope classes, or in specific classes as required.

Examples:

Standalone usage

class BasePart < Hanami::View::Part
  include Hanami::View::Helpers::TagHelper
end

class BaseScope < Hanami::View::Scope
  include Hanami::View::Helpers::TagHelper
end

class BaseView < Hanami::View
  config.part_class = BasePart
  config.scope_class = BaseScope
end

Since:

  • 2.1.0

Defined Under Namespace

Classes: TagBuilder

Instance Method Summary collapse

Instance Method Details

#build_tag_values(*args) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.1.0



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/hanami/view/helpers/tag_helper.rb', line 168

def build_tag_values(*args)
  tag_values = []

  args.each do |tag_value|
    case tag_value
    when Hash
      tag_value.each do |key, val|
        tag_values << key.to_s if val && !key.to_s.empty?
      end
    when Array
      tag_values.concat build_tag_values(*tag_value)
    else
      tag_values << tag_value.to_s unless tag_value.to_s.empty?
    end
  end

  tag_values
end

#class_namesObject

See Also:

Since:

  • 2.1.0



162
163
164
# File 'lib/hanami/view/helpers/tag_helper.rb', line 162

def class_names(...)
  token_list(...)
end

Returns an anchor tag for the given contents and URL.

The tag's contents are automatically escaped (unless marked as HTML safe).

Uses the #tag builder to prepare the tag, so all tag builder options are also used.

Examples:

link_to("Home", "/")
# => <a href="/">Home</a>

link_to("/") { "Home" }
# => <a href="/">Home</a>

link_to("Home", "/", class: "button") %>
# => <a href="/" class="button">Home</a>

Escaping

link_to("<script>alert('xss')</script>", "/")
# => <a href="/">&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;</a>

link_to("/") { "<script>alert('xss')</script>" }
# => <a href="/">&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;</a>

Overloads:

  • #link_to(content, url, **attributes) ⇒ String

    Returns a tag using a given string as the contents.

    Parameters:

    • content (String)

      content used in the a tag

    • url (String)

      URL to be used in the href attribute

    • attributes (Hash)

      HTML attributes to include in the tag

  • #link_to(url, **attributes, &block) ⇒ String

    Returns a tag using the given block's return value as the contents.

    Parameters:

    • url (String)

      URL to be used in the href attribute

    • attributes (Hash)

      HTML attributes to include in the tag

    • block (Proc)

      block that returns the contents of the tag

Returns:

  • (String)

    HTML markup for the anchor tag

See Also:

Since:

  • 2.1.0



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/hanami/view/helpers/tag_helper.rb', line 115

def link_to(content, url = nil, **attributes, &block)
  if block
    raise ArgumentError if url && content

    url = content
    content = nil
  end

  attributes[:href] = url or raise ArgumentError

  tag.a(content, **attributes, &block)
end

#tagObject

Returns a tag builder for building HTML tag strings.

Examples:

General usage

tag.div # => <div></div>
tag.img # => <img>

tag.div("hello")        # => <div>hello</div>
tag.div { "hello" }     # => <div>hello</div>
tag.div(tag.p("hello")) # => <div><p>hello</p></div>

tag.div(class: ["a", "b"])              # => <div class="a b"></div>
tag.div(class: {"a": true, "b": false}) # => <div class="a"></div>

tag.div(id: "el", data: {x: "y"}) # => <div id="el" data-x="y"></div>
tag.div(id: "el", aria: {x: "y"}) # => <div id="el" aria-x="y"></div>

tag.custom_tag("hello") # => <custom-tag>hello</custom-tag>

Escaping

tag.p("<script>alert()</script>")         # => <p>&lt;script&gt;alert()&lt;/script&gt;</p>
tag.p(class: "<script>alert()</script>")  # => <p class="&lt;script&gt;alert()&lt;/script&gt;"></p>
tag.p("<em>safe content</em>".html_safe)  # => <p><em>safe content</em></p>

Within templates

<%= tag.div(id: "el") do %>
  <p>Template content can be mixed in.</p>
  <%= tag.p("Also nested tag builders.") %>
<% end %>

Since:

  • 2.1.0



68
69
70
# File 'lib/hanami/view/helpers/tag_helper.rb', line 68

def tag
  tag_builder
end

#tag_builderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.1.0



189
190
191
192
193
# File 'lib/hanami/view/helpers/tag_helper.rb', line 189

def tag_builder
  @tag_builder ||= begin
    TagBuilder.new(inflector: tag_builder_inflector)
  end
end

#tag_builder_inflectorObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.1.0



197
198
199
200
201
202
203
204
205
206
# File 'lib/hanami/view/helpers/tag_helper.rb', line 197

def tag_builder_inflector
  if respond_to?(:_context)
    return _context.inflector
  end

  # TODO: When hanami-view moves to Zeitwerk (and the only external require is for
  # "dry/view"), remove this.
  require "dry/inflector"
  Dry::Inflector.new
end

#token_list(*args) ⇒ String

Returns a string of space-separated tokens from a range of given arguments.

This is intended for building an HTML tag attribute value, such as a list of class names.

Examples:

token_list("foo", "bar")
# => "foo bar"

token_list("foo", "foo bar")
# => "foo bar"

token_list({ foo: true, bar: false })
# => "foo"

token_list(nil, false, 123, "", "foo", { bar: true })
# => "123 foo bar"

Returns:

Since:

  • 2.1.0



149
150
151
152
153
154
155
156
# File 'lib/hanami/view/helpers/tag_helper.rb', line 149

def token_list(*args)
  tokens = build_tag_values(*args).flat_map { |value|
    safe = value.html_safe?
    value.split(/\s+/).map { |s| safe ? s.html_safe : s }
  }

  EscapeHelper.escape_join(tokens, " ")
end