class HtmlGen::Element
This class can be used to generate HTML.
Examples¶ ↑
ele = HtmlGen::Element.new(:a) #=> #<HtmlGen::Element:0x00000000e5f650 @attr={}, @name=:a, @classes=[], @str_html="" ...> ele.classes << "custom_link" ele.css["font-weight"] = "bold" ele.attr[:href] = "http://www.youtube.com" b = ele.add_ele(:b) b.str = "Title of link" ele.html #=> "<a href=\"http://www.youtube.com\" style=\"font-weight: bold;\" class=\"custom_link\">\n\t<b>\n\t\tTitle of link\n\t</b>\n</a>\n"
Constants
- FORBIDDEN_SHORT
Attributes
attr[R]
classes[R]
css[R]
data[R]
Data hash which will nest keys.
eles[RW]
An array holding all the sub-elements of this element.
name[RW]
The name of the element. “a” for <a> and such.
str[RW]
Public Class Methods
new(name, args = {})
click to toggle source
You can give various arguments as shortcuts to calling the methods. You can also decide what should be used for newline and indentation.
HtmlGen::Element.new(:b, { css: {"font-weight" => "bold"}, attr: {"href" => "http://www.youtube.com"}, classes: ["class1", "class2"], str: "A title", str_html: "Some custom URL as title", nl: "\n", inden: "\t", eles: [HtmlGen::Element.new("i", str: "Hello world!") })
# File lib/html_gen/element.rb, line 65 def initialize(name, args = {}) raise "'name' should be a string or a symbol but was a '#{name.class.name}'." if !name.is_a?(String) && !name.is_a?(Symbol) @name = name {attr: {}, data: {}, classes: [], str_html: "", str: "", css: {}, eles: [], nl: "\n", inden: " "}.each do |arg, default_val| if args[arg] instance_variable_set("@#{arg}", args[arg]) else instance_variable_set("@#{arg}", default_val) end args.delete(arg) end raise "Unknown arguments: '#{args.keys.join(",")}'." unless args.empty? end
Public Instance Methods
add_ele(name, args = {})
click to toggle source
Adds a sub-element to the element.
Examples¶ ↑
element = HtmlGen::Element.new("a") another_ele = element.add_ele("b") another_ele.str = "Hello world!" element.html #=> "<a>\n\t<b>\n\t\tHello world!\n\t</b>\n</a>\n"
# File lib/html_gen/element.rb, line 88 def add_ele(name, args = {}) ele = HtmlGen::Element.new(name, args.merge(nl: @nl, inden: @inden)) @eles << ele ele end
Also aliased as: add
add_html(html)
click to toggle source
Add a text-element to the element.
# File lib/html_gen/element.rb, line 104 def add_html(html) ele = HtmlGen::TextEle.new(html: html, inden: @inden, nl: @nl) @eles << ele ele end
add_html_if_safe(html)
click to toggle source
# File lib/html_gen/element.rb, line 110 def add_html_if_safe(html) if html.respond_to?(:html_safe?) && html.html_safe? add_html(html) else add_str(html) end end
add_str(str)
click to toggle source
Add a text-element to the element.
# File lib/html_gen/element.rb, line 97 def add_str(str) ele = HtmlGen::TextEle.new(str: str, inden: @inden, nl: @nl) @eles << ele ele end
convert_data_attributes_to_data()
click to toggle source
# File lib/html_gen/element.rb, line 267 def convert_data_attributes_to_data @attr.delete_if do |key, value| match = key.to_s.match(/\Adata-(.+)\Z/) if match data_keys = match[1].split("-") last_key = data_keys.pop current_data_element = @data data_keys.each do |key_part| current_data_element = current_data_element[key_part] ||= {} end current_data_element[last_key] = value true else false end end end
convert_style_to_css()
click to toggle source
Converts the content of the 'style'-attribute to css-hash-content.
# File lib/html_gen/element.rb, line 243 def convert_style_to_css if !@attr[:style].to_s.strip.empty? style = @attr[:style] elsif !@attr["style"].to_s.strip.empty? style = @attr["style"] else raise "No style set in element." end loop do if (match = style.match(/\A\s*(\S+?):\s*(.+?)\s*(;|\Z)/)) style.gsub!(match[0], "") key = match[1] val = match[2] raise "Such a key already exists in CSS-hash: '#{key}'." if @css.key?(key) @css[key] = val elsif (match = style.slice!(/\A\s*\Z/)) break else raise "Dont know what to do with style-variable: '#{style}'." end end end
eles_names()
click to toggle source
Returns the names of all sub-elements in an array.
# File lib/html_gen/element.rb, line 233 def eles_names names = [] @eles.each do |ele| names << ele.name end names end
html(args = {})
click to toggle source
Returns the HTML for the element. To avoid indentation and newlines you can use the 'pretty'-argument:
element.html(pretty: false)
# File lib/html_gen/element.rb, line 121 def html(args = {}) if args[:level] level = args[:level] else level = 0 end if args.key?(:pretty) pretty = args[:pretty] else pretty = true end # Used for keeping 'pretty'-value and correct indentation according to parent elements. pass_args = {level: (level + 1), pretty: pretty, inden: @inden} # Clone the attributes-hash since we are going to add stuff to it, and it shouldnt be reflected # (if 'html' is called multiple times, it will bug unless we clone). attr = @attr.clone # Start generating the string with HTML (possible go give a custom 'str'-variable where the content should be pushed to). if args[:str] str = args[:str] else str = "" end str << @inden * level if pretty && level > 0 str << "<#{@name}" # Add content from the 'css'-hash to the 'style'-attribute in the right format. unless @css.empty? style = "" @css.each do |key, val| style << "; " unless style.empty? style << "#{key}: #{val};" end if attr[:style] && !attr[:style].empty? attr[:style] << "; #{style}" else attr[:style] = style end end # Add content from the 'classes'-array to the 'class'-attribute in the right format. unless @classes.empty? class_str = @classes.join(" ") if @attr[:class] && !@attr[:class].empty? attr[:class] << " #{class_str}" else attr[:class] = class_str end end # Write out the attributes to the string. attr.each do |key, val| str << " #{key}=\"#{HtmlGen.escape_html(val)}\"" end str << " #{data_attributes(@data, "data")}" if @data.any? forbidden_short = FORBIDDEN_SHORT.include?(@name.to_s) skip_pretty = false if @eles.empty? && @str.empty? && @str_html.empty? && !forbidden_short # If no sub-string, sub-HTML or sub-elements are given, we should end the HTML with " />". str << " />" str << @nl if pretty else # Write end-of-element and then all sub-elements. str << ">" if @eles.empty? && @str.empty? && @str_html.empty? && forbidden_short skip_pretty = true end str << @nl if pretty && !skip_pretty unless @str.empty? str << @inden * (level + 1) if pretty if @str.respond_to?(:html_safe?) && @str.html_safe? str << @str else str << HtmlGen.escape_html(@str) end str << @nl if pretty end unless @str_html.empty? str << @inden * (level + 1) if pretty str << @str_html str << @nl if pretty end @eles.each do |subele| str << subele.html(pass_args) end str << @inden * level if pretty && level > 0 && !skip_pretty str << "</#{@name}>" str << @nl if pretty end str = str.html_safe if str.respond_to?(:html_safe) str end
Private Instance Methods
data_attributes(data_hash, prev_key)
click to toggle source
# File lib/html_gen/element.rb, line 291 def data_attributes(data_hash, prev_key) html = "" data_hash.each do |key, value| key = key.to_s.tr("_", "-") if key.is_a?(Symbol) if value.is_a?(Hash) html << " " unless html.empty? html << data_attributes(value, "#{prev_key}-#{key}").to_s else html << " " unless html.empty? html << "#{prev_key}-#{key}=\"#{HtmlGen.escape_html(value)}\"" end end html end