{"id":26510120,"url":"https://github.com/timcraft/hom","last_synced_at":"2025-03-21T01:40:13.243Z","repository":{"id":56876581,"uuid":"2234267","full_name":"timcraft/hom","owner":"timcraft","description":"A straightforward API for generating HTML","archived":false,"fork":false,"pushed_at":"2024-01-11T15:13:16.000Z","size":50,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-15T23:15:33.974Z","etag":null,"topics":["html","ruby","xss"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timcraft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-08-19T14:03:47.000Z","updated_at":"2023-01-16T10:53:47.000Z","dependencies_parsed_at":"2023-02-10T02:35:17.508Z","dependency_job_id":null,"html_url":"https://github.com/timcraft/hom","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcraft%2Fhom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcraft%2Fhom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcraft%2Fhom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timcraft%2Fhom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timcraft","download_url":"https://codeload.github.com/timcraft/hom/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244722654,"owners_count":20499151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","ruby","xss"],"created_at":"2025-03-21T01:40:12.785Z","updated_at":"2025-03-21T01:40:13.228Z","avatar_url":"https://github.com/timcraft.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hom\n\n[![Gem Version](https://badge.fury.io/rb/hom.svg)](https://badge.fury.io/rb/hom) [![Test Status](https://github.com/timcraft/hom/actions/workflows/test.yml/badge.svg)](https://github.com/timcraft/hom/actions/workflows/test.yml)\n\n\nA straightforward API for generating HTML.\n\n\n## Motivation\n\nHOM helps you implement HTML presentation logic in your code. Things like\nnavigation links, select boxes, sets of checkboxes; anything with behaviour\nthat is too complex for your templates.\n\n\n## Installation\n\n    $ gem install hom\n\n\n## Quick start\n\n```ruby\nrequire 'hom'\n\nputs HOM::Element.new(:h1, nil, 'hello world')\n```\n\n\n## Using HOM::Element\n\nCreate instances of HOM::Element to represent DOM elements. The first\nconstructor argument is a symbol representing the tag name. For example,\nyou can represent a line break element like this:\n\n```ruby\nHOM::Element.new(:br)\n```\n\nThe second constructor argument represents the element attributes, and can be\nnil, a single symbol/string, a hash, or an array of hashes and symbols/strings.\nFor example, here's how you'd represent some input elements:\n\n```ruby\nHOM::Element.new(:input, :disabled)\n\nHOM::Element.new(:input, {type: :text, size: 30})\n\nHOM::Element.new(:input, [{type: :text, size: 30}, :disabled])\n```\n\nThe third constructor argument is the inner content, which can be a string,\nanother element object, or an array of child nodes. For example, here's how\nyou can represent various elements with inner content:\n\n```ruby\nspan = HOM::Element.new(:span, nil, '')\n\nh1 = HOM::Element.new(:h1, {}, 'hello world')\n\nimage = HOM::Element.new(:img, {src: 'image.png', width: 100, height: 30})\n\nlink = HOM::Element.new(:a, {target: :_blank, href: '/'}, image)\n\nlist = HOM::Element.new(:ul, nil, (1..3).map { |n| HOM::Element.new(:li, nil, n) })\n```\n\nCalling #to_s on a HOM::Element object will return a string containing the\ngenerated HTML markup. HOM::Element objects are safe to use directly in Rails\ntemplates, all escaping is handled automatically.\n\n\n## Using HOM::Entity\n\nCreate instances of HOM::Entity to represent HTML entities. Use an integer\nargument for numeric entities and a symbol/string argument for named entities,\nfor example:\n\n```ruby\nHOM::Entity.new(160)\n\nHOM::Entity.new(:nbsp)\n```\n\n\n## Using HOM::NodeList\n\nUse HOM::NodeList to group nodes together without having to wrap them in an\nouter element. For example:\n\n```ruby\nHOM::NodeList.new(['This is a ', HOM::Element.new(:strong, nil, 'Contrived'), ' example'])\n```\n\nCalling #to_s on a HOM::NodeList object will return a string containing the\ngenerated HTML markup. Calling #join will insert separator nodes, a bit like\nArray#join, but returning HTML safe output.\n\n\n## XSS 101\n\nDo you have helper methods that look like this:\n\n```ruby\ndef user_name(user)\n  \"\u003cstrong\u003e#{user.name}\u003c/strong\u003e\".html_safe\nend\n```\n\nBzzzt, that's a security vulnerability right there. If you're using Rails\nyou should have code that looks like this:\n\n```ruby\ndef user_name(user)\n  content_tag(:strong, user.name)\nend\n```\n\nThe content_tag helper will automatically escape content not explicitly\nmarked as safe. HOM will do very much the same thing, the equivalent helper\nmethod would look like this:\n\n```ruby\ndef user_name(user)\n  HOM::Element.new(:strong, nil, user.name)\nend\n```\n\nMoral of the story: building up fragments of HTML using string interpolation\nand concatenation is highly error prone. Solution: use content_tag or HOM to\nsafely build your content, and audit your usage of html_safe.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimcraft%2Fhom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimcraft%2Fhom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimcraft%2Fhom/lists"}