Project

hom

0.0
No release in over 3 years
Low commit activity in last 3 years
A straightforward API for generating HTML
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

hom

Gem Version Test Status

A straightforward API for generating HTML.

Motivation

HOM helps you implement HTML presentation logic in your code. Things like navigation links, select boxes, sets of checkboxes; anything with behaviour that is too complex for your templates.

Installation

$ gem install hom

Quick start

require 'hom'

puts HOM::Element.new(:h1, nil, 'hello world')

Using HOM::Element

Create instances of HOM::Element to represent DOM elements. The first constructor argument is a symbol representing the tag name. For example, you can represent a line break element like this:

HOM::Element.new(:br)

The second constructor argument represents the element attributes, and can be nil, a single symbol/string, a hash, or an array of hashes and symbols/strings. For example, here's how you'd represent some input elements:

HOM::Element.new(:input, :disabled)

HOM::Element.new(:input, {type: :text, size: 30})

HOM::Element.new(:input, [{type: :text, size: 30}, :disabled])

The third constructor argument is the inner content, which can be a string, another element object, or an array of child nodes. For example, here's how you can represent various elements with inner content:

span = HOM::Element.new(:span, nil, '')

h1 = HOM::Element.new(:h1, {}, 'hello world')

image = HOM::Element.new(:img, {src: 'image.png', width: 100, height: 30})

link = HOM::Element.new(:a, {target: :_blank, href: '/'}, image)

list = HOM::Element.new(:ul, nil, (1..3).map { |n| HOM::Element.new(:li, nil, n) })

Calling #to_s on a HOM::Element object will return a string containing the generated HTML markup. HOM::Element objects are safe to use directly in Rails templates, all escaping is handled automatically.

Using HOM::Entity

Create instances of HOM::Entity to represent HTML entities. Use an integer argument for numeric entities and a symbol/string argument for named entities, for example:

HOM::Entity.new(160)

HOM::Entity.new(:nbsp)

Using HOM::NodeList

Use HOM::NodeList to group nodes together without having to wrap them in an outer element. For example:

HOM::NodeList.new(['This is a ', HOM::Element.new(:strong, nil, 'Contrived'), ' example'])

Calling #to_s on a HOM::NodeList object will return a string containing the generated HTML markup. Calling #join will insert separator nodes, a bit like Array#join, but returning HTML safe output.

XSS 101

Do you have helper methods that look like this:

def user_name(user)
  "<strong>#{user.name}</strong>".html_safe
end

Bzzzt, that's a security vulnerability right there. If you're using Rails you should have code that looks like this:

def user_name(user)
  content_tag(:strong, user.name)
end

The content_tag helper will automatically escape content not explicitly marked as safe. HOM will do very much the same thing, the equivalent helper method would look like this:

def user_name(user)
  HOM::Element.new(:strong, nil, user.name)
end

Moral of the story: building up fragments of HTML using string interpolation and concatenation is highly error prone. Solution: use content_tag or HOM to safely build your content, and audit your usage of html_safe.