class Hanami::View::Helpers::TagHelper::TagBuilder

Tag builder returned from {TagHelper#tag}.

@see TagHelper#tag

@api public @since 2.1.0

Constants

ARIA_PREFIXES

@api private @since 2.1.0

ATTRIBUTE_SEPARATOR

@api private @since 2.1.0

BOOLEAN_ATTRIBUTES

@api private @since 2.1.0

DATA_PREFIXES

@api private @since 2.1.0

HTML_VOID_ELEMENTS

@api private @since 2.1.0

PRE_CONTENT_STRINGS

@api private @since 2.1.0

SVG_SELF_CLOSING_ELEMENTS

@api private @since 2.1.0

TAG_TYPES

@api private @since 2.1.0

Attributes

inflector[R]

@api private @since 2.1.0

Public Class Methods

new(inflector:) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 79
def initialize(inflector:)
  @inflector = inflector
end

Public Instance Methods

attributes(**attributes) click to toggle source

Transforms a Hash into HTML Attributes, ready to be interpolated into ERB.

@example

<input <%= tag.attributes(type: :text, aria: { label: "Search" }) %> >
# => <input type="text" aria-label="Search">

@api public @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 92
def attributes(**attributes)
  tag_options(**attributes).to_s.strip.html_safe
end
boolean_tag_option(key) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 178
def boolean_tag_option(key)
  %(#{key}="#{key}")
end
content_tag_string(name, content, **options) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 119
def content_tag_string(name, content, **options)
  tag_options = tag_options(**options) unless options.empty?

  name = EscapeHelper.escape_xml_name(name)
  content = EscapeHelper.escape_html(content)

  "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
end
p(*args, **options, &block) click to toggle source

Returns a ‘<p>` HTML tag.

@api public @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 100
def p(*args, **options, &block)
  tag_string(:p, *args, **options, &block)
end
tag_option(key, value) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 184
def tag_option(key, value)
  key = EscapeHelper.escape_xml_name(key)

  case value
  when Array, Hash
    value = TagHelper.build_tag_values(value) if key.to_s == "class"
    value = EscapeHelper.escape_join(value, " ")
  when Regexp
    value = EscapeHelper.escape_html(value.source)
  else
    value = EscapeHelper.escape_html(value)
  end
  value = value.gsub('"', "&quot;") if value.include?('"')

  %(#{key}="#{value}")
end
tag_options(**options) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 130
def tag_options(**options)
  return if options.none?

  output = +""

  options.each_pair do |key, value|
    type = TAG_TYPES[key]

    if type == :data && value.is_a?(Hash)
      value.each_pair do |k, v|
        next if v.nil?

        output << ATTRIBUTE_SEPARATOR
        output << prefix_tag_option(key, k, v)
      end
    elsif type == :aria && value.is_a?(Hash)
      value.each_pair do |k, v|
        next if v.nil?

        case v
        when Array, Hash
          tokens = TagHelper.build_tag_values(v)
          next if tokens.none?

          v = EscapeHelper.escape_join(tokens, " ")
        else
          v = v.to_s
        end

        output << ATTRIBUTE_SEPARATOR
        output << prefix_tag_option(key, k, v)
      end
    elsif type == :boolean
      if value
        output << ATTRIBUTE_SEPARATOR
        output << boolean_tag_option(key)
      end
    elsif !value.nil?
      output << ATTRIBUTE_SEPARATOR
      output << tag_option(key, value)
    end
  end

  output unless output.empty?
end
tag_string(name, content = nil, **options) { || ... } click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 106
def tag_string(name, content = nil, **options)
  content = yield if block_given?
  self_closing = SVG_SELF_CLOSING_ELEMENTS.include?(name)

  if (HTML_VOID_ELEMENTS.include?(name) || self_closing) && content.nil?
    "<#{inflector.dasherize(name.to_s)}#{tag_options(**options)}#{self_closing ? " />" : ">"}".html_safe
  else
    content_tag_string(inflector.dasherize(name.to_s), content || "", **options)
  end
end

Private Instance Methods

method_missing(called, *args, **options, &block) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 205
def method_missing(called, *args, **options, &block)
  tag_string(called, *args, **options, &block)
end
prefix_tag_option(prefix, key, value) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 217
def prefix_tag_option(prefix, key, value)
  key = "#{prefix}-#{inflector.dasherize(key.to_s)}"

  unless value.is_a?(String) || value.is_a?(Symbol)
    value = value.to_json
  end

  tag_option(key, value)
end
respond_to_missing?(*args) click to toggle source

@api private @since 2.1.0

# File lib/hanami/view/helpers/tag_helper/tag_builder.rb, line 211
def respond_to_missing?(*args)
  true
end