A utility library for generating HTML strings.
Add this line to your application's Gemfile:
gem 'berns'
And then execute:
bundle
Or install it yourself as:
gem install berns
Note: Berns is only tested on Ruby's MRI/CRuby interpreter version 2.7 and greater. Berns version 3.x and below support Ruby 2.5. Contributions are welcome to get JRuby or TruffleRuby working.
Note that all return string values will be UTF-8 encoded.
The void
method generates a void HTML element i.e. one without any content. It
takes either a symbol or a string and an optional hash of HTML attributes.
Berns.void('br') # => '<br>'
Berns.void('br', class: 'br-class') # => '<br class="br-class">'
The element
method generates a standard HTML element i.e. one with optional
content. It takes either a symbol or a string, an optional hash of HTML
attributes, and an optional block of content. If provided, the block should
return a string.
Berns.element('div') # => '<div></div>'
Berns.element('div', class: 'div-class') # => '<div class="div-class"></div>'
Berns.element('div', class: 'div-class') { 'Content' } # => '<div class="div-class">Content</div>'
The to_attribute
method generates an HTML attribute string. If the value is a
hash then the attribute is treated as a prefix.
Berns.to_attribute('class', 'my-class another-class') # => 'class="my-class another-class"'
Berns.to_attribute('data', { foo: 'bar' }) # => 'data-foo="bar"'
All attribute values are HTML-escaped using k0kubun/hescape written by Takashi Kokubun.
The to_attributes
method generates an HTML attribute string from a hash by
calling to_attribute
for each key/value pair.
Berns.to_attributes({ 'data' => { foo: 'bar' }, 'class' => 'my-class another-class' }) # => 'data-foo="bar" class="my-class another-class"'
The escape_html
method escapes HTML entities in strings using
k0kubun/hescape written by Takashi Kokubun. As noted in the hescape
repository, it should be the same as CGI.escapeHTML
.
Berns.escape_html('<"tag"') # => '<"tag"'
The sanitize
method strips HTML tags from strings.
Berns.sanitize('This <span>should be clean</span>') # => 'This should be clean'
Note that this is an extremely naive implementation of HTML sanitization that literally just looks for "<" and ">" characters and removes the contents between them. This should probably only be used on trusted strings.
The build
method uses Berns::Builder
to let you create HTML strings using a
DSL.
Berns.build { h1 { 'Heading' } } # => '<h1>Heading</h1>'
See below for more on Berns::Builder
.
Added in version 3.4.0 and heavily inspired by the likes of
Papercraft, Markaby, and Arbre, the
Berns::Builder
class lets you create HTML strings using a DSL.
template = Berns::Builder.new do
h1 { 'Heading' }
p(class: 'paragraph') do
text 'Bare text here.'
b { 'Bold text here' }
end
end
Within the block provided to Berns::Builder.new
every standard element method,
void element method, #element
, and #void
are available as methods and each
time you use one of those methods the result is appended to an internal buffer.
In addition, the #text
method appends HTML escaped text to the buffer and
#raw
appends text to the buffer without modification.
The block provided to Berns::Builder.new
can take both positional and keyword
arguments.
template = Berns::Builder.new do |content, title:|
h1 { title }
p(class: 'paragraph') { content }
end
template.call('Some text.', title: 'The title') # =>
# <h1>
# The title
# </h1>
# <p>
# Some text.
# </p>
Once initialized, the #call
method will render the template to a string. Any
arguments, positional or keyword, are passed through as-is to the block provided
to #new
.
string = template.call # =>
# <h1>
# Heading
# </h1>
# <p class='paragraph'>
# Bare text here.
# <b>
# Bold text here.
# </b>
# </p>
In addition to initializing a new instance of Berns::Builder
, you can
construct and render a template to a string all at once with Berns.build
.
Berns.build do
h1 { 'Heading' }
p(class: 'paragraph') do
text 'Bare text here.'
b { 'Bold text here' }
end
end # =>
# <h1>
# Heading
# </h1>
# <p class='paragraph'>
# Bare text here.
# <b>
# Bold text here.
# </b>
# </p>
All standard and void HTML elements are defined as methods on Berns, so you can
create e.g. a link with Berns.a
. Below is the full list of standard elements
which are also available in the constant Berns::STANDARD
as an array of
symbols.
a abbr address article aside audio b bdi bdo blockquote body button canvas
caption cite code colgroup datalist dd del details dfn dialog div dl dt em
fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header html i
iframe ins kbd label legend li main map mark menu meter nav noscript object ol
optgroup option output p picture pre progress q rp rt ruby s samp script section
select small span strong style sub summary table tbody td template textarea
tfoot th thead time title tr u ul var video
Below is the full list of void elements that are defined as singleton methods on
Berns which are also available in the constant Berns::VOID
as an array of
symbols.
area base br col embed hr img input link menuitem meta param source track wbr
Berns 3 was a total rewrite from a pure Ruby implementation to one powered by a C extension. That rewrite is about three times faster than the pure Ruby implementation used in version 2. See the file benchmarks/performance.rb for the benchmark code.
Warming up --------------------------------------
ruby 27.521k i/100ms
c-ext 74.915k i/100ms
Calculating -------------------------------------
ruby 275.913k (± 1.0%) i/s - 1.404M in 5.087516s
c-ext 813.113k (± 1.0%) i/s - 4.120M in 5.067902s
Comparison:
c-ext: 813113.3 i/s
ruby: 275913.5 i/s - 2.95x (± 0.00) slower
The name "Berns" is taken from the name of the inventor of HTML, Sir Tim Berners-Lee.