Project

roda-tags

0.0
A long-lived project that still receives updates
HTML tags functionality for Roda.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

~> 1.13.0, >= 1.13.0
~> 6.3.0, >= 6.3.0
~> 2.4.0, >= 2.4.0
~> 3.85.0, >= 3.85.0
 Project Readme

Roda::Tags

Ruby - Gem Version - Minitest Style Guide

Coverage: 100%

A Roda plugin providing easy creation of flexible HTML tags within Roda apps or Roda plugins.

Extensively tested and with 100% code test coverage.

Installation

Add this line to your application's Gemfile:

gem 'roda-tags'

And then execute:

bundle

Or install it yourself as:

gem install roda-tags

Getting Started

To use Roda::Tags just ensure the gem is included in the Gemfile and then...

...add the plugin to your app...

class MyApp < Roda

  plugin :tags  # see Configurations below for options
  # or
  plugin :tag_helpers # , options

  # <snip...>
end

...or include the plugin in your own Roda plugin.

class Roda
  module RodaPlugins
    module YourPlugin

      def self.load_dependencies(app, opts={})
        app.plugin :tags, opts
        # or
        app.plugin :tag_helpers, opts
      end

      # <snip...>
    end
  end
end

Usage

TODO: add usage notes here...

Key Methods / Functionality

Roda::Tags contains two plugins - [:tags, :tag_helpers] - that can be used independently or together.

Note! The :tags plugin is loaded by the :tag_helpers plugin.


1. :tags Plugin

This plugin have one key public method - tag(), which supports this dynamic syntax:

-- tag(*args, &block)

tag(name)
tag(name, &block)

tag(name, content)
tag(name, content, attributes)
tag(name, content, attributes, &block)

tag(name, attributes)
tag(name, attributes, &block)

This makes the method very flexible as can be seen below.

Self closing tags

tag(:br)   #=> <br> or <br/> if XHTML

tag(:hr, class: :divider)  #=>  <hr class="divider">

Multi line tags

tag(:div)  #=>  <div></div>

tag(:div, 'content')
  #  <div>
  #    content
  #  </div>

tag(:div, 'content', id: 'comment')
  #  <div id="comment">
  #    content
  #  </div>

 # NB! no content
tag(:div, id: :comment)
  #=> <div id="comment"></div>

Single line tags

tag(:h1,'Header')  #=>  <h1>Header</h1>

tag(:abbr, 'UN', title: "United Nations")  #=>  <abbr title="United Nations">UN</abbr>

Working with blocks

tag(:div) do
  tag(:p, 'Hello World')
end
  #  <div>
  #    <p>Hello World</p>
  #  </div>

<% tag(:ul) do %>
  <li>item 1</li>
  <%= tag(:li, 'item 2') %>
  <li>item 3</li>
<% end %>
  #  <ul>
  #    <li>item 1</li>
  #    <li>item 2</li>
  #    <li>item 3</li>
  #  </ul>

 # NOTE: ignores tag contents when given a block
<% tag(:div, 'ignored tag-content') do %>
  <%= tag(:label, 'Comments:', for: :comments) %>
  <%= tag(:textarea,'textarea contents', id: :comments) %>
<% end %>
  #  <div>
  #    <label for="comments">Comments:</label>
  #    <textarea id="comments">
  #      textarea contents
  #    </textarea>
  #  </div>

Boolean attributes

tag(:input, type: :checkbox, checked: true)
  #=> <input checked="checked" type="checkbox">

tag(:option, 'Roda', value: "1" selected: true)
  #=> <option selected="selected" value="1">Roda</option>

tag(:option, 'PHP', value: "0" selected: false)
  #=> <option value="0">PHP</option>

The plugin also have a few other public helper methods:

-- merge_attr_classes(attr, *classes)

Updates attr[:class] in the hash with the given classes and returns attr.

attr = { class: 'alert', id: :idval }

merge_attr_classes(attr, 'alert-info')
  #=> { class: 'alert alert-info', id: :idval }

merge_attr_classes(attr, [:alert, 'alert-info'])
  #=> { class: 'alert alert-info', id: :idval }

-- merge_classes(*classes)

Returns an alphabetised string from all given class values.

The method correctly handles a combination of arrays, strings & symbols being passed in.

attr = { class: 'alert', id: :idval }

merge_classes(attr[:class], ['alert', 'alert-info'])  #=> 'alert alert-info'

merge_classes(attr[:class], :text)  #=> 'alert text'

merge_classes(attr[:class], [:text, :'alert-info'])  #=> 'alert alert-info text'

Included Helper methods

The :tags plugin also includes a few useful public helper methods for use within other methods or gems.

-- capture(block='')

Captures and returns a captured ERB block and restores the buffer afterwards.

-- capture_html(*args, &block)

Captures the HTML from a block of template code for ERB or HAML.

def some_method(*args, &block)
 # <snip...>
 res = capture_html(&block)
 # <snip...>
end

-- concat_content(text="")

Outputs the given content to the buffer directly.

concat_content("This will be concatenated to the buffer")

-- block_is_template?(block)

Returns true if the block is from an ERB or HAML template; false otherwise. Used to determine if contents should be returned or concatenated to output.


2. :tag_helpers Plugin

-- form_tag(action, attrs={}, &block)

Constructs a <form> without an object based on options passed.

form_tag('/register') do
 ...
end
 #   <form action="/register" id="register-form" method="post">
 #    ...
 #   </form>

Automatically adds a hidden faux method when :method is NOT either POST or GET.

form_tag('/user/1/profile', method: :put, id: 'profile-form')
  ...
end
  #  <form action="/user/1/profile" id="profile-form" method="post" >
  #    <input name="_method" type="hidden" value="put"/>
  #    ...
  #  </form>

Add multipart support via:

form_tag('/upload', multipart: true)
 # or
form_tag('/upload', multipart: 'multipart/form-data')
 # or
form_tag('/upload', enctype: 'multipart/form-data')
  #  <form enctype="multipart/form-data" method="post" action="/upload">
  #     ...
  #  </form>

-- label_tag(field, attrs={}, &block)

Constructs a <label> tag from the given options.

By default appends ':' to the label name, based upon the plugin config :tags_label_append value.

label_tag(:name)
  #=> <label for="name">Name:</label>

label_tag(:name, label: 'Custom label', class: 'sr-only')
  #=> <label class="sr-only" for="name">Custom label:</label>

 # uses a humanized version of the label name if { label: nil }
label_tag(:name, label: nil)
  #=> <label for="name">Name:</label>

 # removes the label text when { label: :false }
label_tag(:name, label: false)
  #=> <label for="name"></label>

By default adds '<span>*</span>' to the label name when { required: true } is passed. Based upon the plugin config :tags_label_required_str value.

label_tag(:name, required: true)
  #=> <label for="name">Name: <span>*</span></label>

Label tags also supports passing blocks.

<% label_tag(:remember_me) do %>
  <%= checkbox_tag :remember_me %>
<% end %>
  #  <label for="remember_me">Remember Me:
  #    <input
  #      class="checkbox"
  #      id="remember_me"
  #      name="remember_me"
  #      type="checkbox"
  #      value="1"
  #    >
  #  </label>

-- hidden_field_tag(name, attrs={})

Constructs a hidden input field from the given options. Only [:value, :id, :name] attributes are allowed.

hidden_field_tag(:snippet_name)
  #=> <input id="snippet_name" name="snippet_name" type="hidden">

hidden_field_tag(:csrf, value: 'tokenval')
  #=> <input id="csrf" name="csrf" type="hidden" value="tokenval">

hidden_field_tag(:snippet_id, id: 'some-id')
  #=> <input id="some-id" name="snippet_id" type="hidden">

 # removing the `:id` attribute completely.
hidden_field_tag(:snippet_name, id: false)
  #=> <input name="snippet_name" type="hidden">

-- text_field_tag(name, attrs={})

  - also aliased as textfield_tag()

Creates a standard <input type="text"...> field from the given options.

text_field_tag(:snippet_name)
  #=> <input class="text" id="snippet_name" name="snippet_name" type="text">

text_field_tag(:name, value: 'some-value')
  #=> <input class="text" id="name" name="name" type="text" value="some-value">

text_field_tag(:name, id: 'some-id')
  #=> <input class="text" id="some-id" name="name" type="text">

 # removing the `:id` attribute completely. NB! bad practice.
text_field_tag(:name, id: false)
  #=> <input class="text" name="name" type="text">

 # append a CSS class to the existing class.
text_field_tag(:name, class: :big)
  #=> <input class="big text" id="name" name="name" type="text">

 # adds a `:title` attribute when passed `:ui_hint`
text_field_tag(:name, ui_hint: 'a user hint')
  #=> <input class="text" id="name" name="name" title="a user hint" type="text">

 # supports `:maxlength` & `:size` attributes
text_field_tag(:ip, maxlength: 15, size: 20)
  #=> <input class="text" id="ip" maxlength="15" name="ip" size="20" type="text">

 # `:disabled` attribute
text_field_tag(:name, disabled: true)
  #=> <input class="text" disabled="disabled" id="name" name="name" type="text">

 # `:readonly` attribute
text_field_tag(:name, readonly: true)
  #=> <input class="text" id="name" name="name" readonly="readonly" type="text">

-- password_field_tag(name, attrs={})

  - also aliased as passwordfield_tag()

Constructs a <input type="password"...> field from the given options.

password_field_tag(:snippet_name)
  #=> <input class="text" id="snippet_name" name="snippet_name" type="password">

password_field_tag(:snippet_name, value: 'some-value')
  #=> <input
  #     class="text"
  #     id="snippet_name"
  #     name="snippet_name"
  #     type="password"
  #     value="some-value">

password_field_tag(:snippet_name, id: 'some-id')
  #=> <input class="text" id="some-id" name="snippet_name" type="password">

password_field_tag(:snippet_name, id: false)
  #=> <input class="text" name="snippet_name" type="password">

 # append a CSS class to the existing class. Default class: `.text`.
password_field_tag(:snippet_name, class: :big )
  #=> <input class="big text" id="snippet_name" name="snippet_name" type="password">

 # adds a `:title` attribute when passed `:ui_hint`
password_field_tag(:name, ui_hint: 'a user hint')
  #=> <input class="text" id="name" name="name" title="a user hint" type="password">

 # supports `:maxlength` & `:size` attributes
password_field_tag(:ip_address, maxlength: 15, size: 20)
  #=> <input
  #    class="text"
  #    id="ip_address"
  #    maxlength="15"
  #    name="ip_address"
  #    size="20"
  #    type="password">

 # `disabled` attribute
password_field_tag(:name, disabled: true)
password_field_tag(:name, disabled: :disabled)
  #=> <input class="text" id="name" disabled="disabled" name="name" type="password">

-- file_field_tag(name, attrs={})

  - also aliased as filefield_tag()

Creates an <input type="file"...> field from given options.

NOTE! If you are using file uploads then you will also need to set the multipart option for the form tag, like this:

<% form_tag('/upload', multipart: true) do %>
  <%= label_tag(:file, label: "File to Upload") %>
  <%= file_field_tag "file" %>
  <%= submit_tag %>
<% end %>

The specified URL will then be passed a File object containing the selected file, or if the field was left blank, a StringIO object.

file_field_tag('attachment')
  #=> <input class="file" id="attachment" name="attachment" type="file">

 # ignores invalid :value attribute.
file_field_tag(:photo, value: 'some-value')
  #=> <input class="file" id="photo" name="photo" type="file">

file_field_tag(:photo, id: 'some-id')
  #=> <input class="file" id="some-id" name="photo" type="file">

 # removing the `:id` attribute completely. NB! bad practice.
file_field_tag(:photo, id: false)
  #=> <input class="file" name="photo" type="file">

 # append a CSS class to the existing class. Default class: `.file`.
file_field_tag(:photo, class: :big )
  #=> <input class="big file" id="photo" name="photo" type="file">

 # adds a `:title` attribute when passed `:ui_hint`.
file_field_tag(:photo, ui_hint: 'a user hint')
  #=> <input class="file" id="photo" name="photo" title="a user hint" type="file">

 # `:disabled` attribute
file_field_tag(:photo, disabled: true)
  #=> <input class="file" disabled="disabled" id="photo" name="photo" type="file">

 # `:accept` attribute is subject to actual browser support.
file_field_tag(:photo, accept: 'image/png,image/jpeg' )
  #=> <input
  #      accept="image/png,image/jpeg"
  #      class="file"
  #      id="photo"
  #      name="photo"
  #      type="file">

-- textarea_tag(name, attrs={})

  - also aliased as text_area_tag()

Constructs a textarea input from the given options.

TODO: enable :escape functionality. How??

  • :escape - By default, the contents of the text input are HTML escaped. If you need unescaped contents, set this to false.
textarea_tag('post')
  #=> <textarea id="post" name="post">\n</textarea>

 # add a value
textarea_tag(:bio, value: @actor.bio)
  #=> <textarea id="bio" name="bio">This is my biography.\n</textarea>

 # set a different :id
textarea_tag(:body, id: 'some-id')
  #=> <textarea id="some-id" name="post">...</textarea>

 # adds a CSS class. NB! :textarea have no default class.
textarea_tag(:body, class: 'big')
  #=> <textarea class="big" id="post" name="post">...</textarea>

 # adds a `:title` attribute when passed `:ui_hint`
textarea_tag(:body, ui_hint: 'a user hint')
  #=> <textarea id="post" name="post" title="a user hint">...</textarea>

 # supports `:rows` & `:cols` attributes
textarea_tag('body', rows: 10, cols: 25)
  #=> <textarea cols="25" id="body" name="body" rows="10">...</textarea>

 # alternative `:size` shortcut to set `:rows` & `:cols`
textarea_tag('body', size: "25x10")
  #=> <textarea cols="25" id="body" name="body" rows="10">...</textarea>

 # `:disabled` attribute
textarea_tag(:description, disabled: true)
  #=> <textarea disabled="disabled" id="description" name="description">
  #   ...
  #   </textarea>

 # `:readonly` attribute
textarea_tag(:description, readonly: true)
  #=> <textarea id="description" name="description" readonly="readonly">
  #    ...
  #   </textarea>

-- field_set_tag(*args, &block)

  - also aliased as fieldset_tag()

Creates a <fieldset..> tag for grouping HTML form elements.

field_set_tag(:actor)
  #  <fieldset id="fieldset-actor">
  #    <legend>Actor</legend>
  #     ...
  #  </fieldset>

 # sets the `<legend>` and `:id` attribute when given a single argument.
field_set_tag('User Details') do
  ...
end
  #  <fieldset id="fieldset-user-details">
  #    <legend>User Details</legend>
  #    ...
  #  </fieldset>

 # supports `:legend` attribute
field_set_tag(:actor, legend: 'Details')
  #  <fieldset id="fieldset-actor">
  #    <legend>Details</legend>
  #    <snip...>

 # remove `<legend>` tag by  `{ legend: false }`
field_set_tag(:actor, legend: 'Details')
  #  <fieldset id="fieldset-actor">
  #    <legend>Details</legend>
  #    <snip...>

 # append a CSS class. NB! fieldset has no other class by default.
field_set_tag(:actor, class: 'legend-class')
  #  <fieldset class="legend-class" id="fieldset-actor">
  #    <snip...>

 # default to 'fieldset' when passed `nil` as the first arg
field_set_tag(nil, class: 'format')
  #  <fieldset class="format" id="fieldset">
  #    <snip...>

 # removing the `:id` attribute completely
field_set_tag('Users', id: false)
  #  <fieldset>
  #    <legend>Users</legend>
  #    <snip...>

-- legend_tag(contents, attrs={})

Return a legend with contents from the given options.

legend_tag('User Details')
  #=> <legend>User Details</legend>

 # adding an :id attribute.
legend_tag('User', id: 'some-id')
  #=> <legend id="some-id">User</legend>

 # adds a CSS class. NB! legend tags have no default class
legend_tag('User', class: 'some-class')
  #=> <legend class="some-class">User</legend>

-- check_box_tag(name, attrs={})

  - also aliased as checkbox_tag()

Creates an <input type="checkbox"...> tag from the given options.

check_box_tag(:accept) || checkbox_tag(:accept)
  #=> <input class="checkbox" id="accept" name="accept" type="checkbox" value="1">

 # providing a value
check_box_tag(:rock, value: 'rock music')
  #=> <input class="checkbox" id="rock" name="rock" type="checkbox" value="rock music">

 # setting a different :id
check_box_tag(:rock, :id => 'some-id')
  #=> <input class="checkbox" id="some-id" name="rock" type="checkbox" value="1">

 # append a CSS class. NB! default class: '.checkbox'
check_box_tag(:rock, class: 'small')
  #=> <input class="small checkbox" id="rock" name="rock" type="checkbox" value="1">

 # adds a `:title` attribute when passed `:ui_hint`
check_box_tag(:rock, ui_hint: 'a user hint')
  #=> <input
  #      class="checkbox"
  #      id="rock"
  #      name="rock"
  #      title="a user hint"
  #      type="checkbox"
  #      value="1">

 # `checked` attribute
check_box_tag(:rock, checked: true)
  #=> <input
  #     checked="checked"
  #     class="checkbox"
  #     id="rock"
  #     name="rock"
  #     type="checkbox"
  #     value="1">

 # `disabled` attribute
check_box_tag(:rock, disabled: true)
  #=> <input
  #     class="checkbox"
  #     disabled="disabled"
  #     id="rock"
  #     name="rock"
  #     type="checkbox"
  #     value="1">

-- radio_button_tag(name, attrs={})

  - also aliased as radiobutton_tag()

Creates a <input type="radio"...> tag from the given options.

NOTE! use groups of radio buttons named the same to allow users to select from a group of options.

radio_button_tag(:accept) || radiobutton_tag(:accept)
  #=> <input class="radio" id="accept_1" name="accept" type="radio" value="1">

radio_button_tag(:rock, value:'rock music')
  #=> <input class="radio" id="rock_rock-music" name="rock" type="radio" value="rock music">

 # setting a different :id.
radio_button_tag(:rock, id: 'some-id')
  #=> <input class="radio" id="some-id_1" name="rock" type="radio" value="1">

 # append a CSS class. NB! default class: '.radio'
radio_button_tag(:rock, class: 'big')
  #=> <input class="big radio" id="rock_1" name="rock" type="radio" value="1">

 # adds a `:title` attribute when passed `:ui_hint`
radio_button_tag(:rock, ui_hint: 'a user hint')
  #=> <input class="radio" id="rock_1" value="1" name="rock" title="a user hint" type="radio">

 # `checked` attribute
radio_button_tag(:yes, checked: true)
  #=> <input checked="checked" class="radio" id="yes_1" name="yes" type="radio" value="1">

 # `disabled` attribute
radio_button_tag(:yes, disabled: true)
  #=> <input disabled="disabled" class="radio" id="yes_1" name="yes" type="radio" value="1">

-- submit_tag(value="Save Form", attrs={})

  - also aliased as submit_button()

Creates a submit button with the text value as the caption.

submit_tag()  || submit_button()
  #=> <input name="submit" type="submit" value="Save Form">

submit_tag(nil)
  #=> <input name="submit" type="submit" value="">

submit_tag('Custom Value')
  #=> <input name="submit" type="submit" value="Custom Value">

 # adds a CSS class. NB! input[:submit] has no other class by default.
submit_tag(class: 'some-class')
  #=> <input class="some-class" name="submit" type="submit" value="Save Form">

 # supports the :disabled attribute.
submit_tag('disabled: true)
  #=> <input disabled="disabled" name="submit" type="submit" value="Save Form">

 # adds a `:title` attribute when passed `:ui_hint`.
submit_tag(ui_hint: 'a user hint')
  #=> <input name="submit" title="a user hint" type="submit" value="Save Form">

-- image_submit_tag(src, attrs={})

Adds a <input src=""...> tag which displays an image.

@img = '/img/btn.png'

image_submit_tag(@img)
  #=> <input src="/img/btn.png" type="image">

image_submit_tag(@img, disabled: true)
  #=> <input disabled="disabled" src="/img/btn.png" type="image">

image_submit_tag(@img, class 'search-button')
  #=> <input class="search-button" src="/img/btn.png" type="image">

-- reset_tag(value='Reset Form', attrs={})

  - also aliased as reset_button()

Creates a reset button with the text value as the caption.

reset_tag() || reset_button()
  #=> <input name="reset" type="reset" value="Reset Form">

reset_tag(nil)
  #=> <input name="reset" type="reset" value="">

reset_tag('Custom Value')
  #=> <input name="reset" type="reset" value="Custom Value">

 # adds a CSS class. NB! input[:reset] has no other class by default
reset_tag(class: 'some-class')
  #=> <input class="some-class" name="reset" type="reset" value="Reset Form">

 # supports the `:disabled` attribute
reset_tag(disabled: true)
  #=> <input disabled="disabled" name="reset" type="reset" value="Reset Form">

 # adds a `:title` attribute when passed `:ui_hint`
reset_tag(ui_hint: 'a user hint')
  #=> <input name="reset" title="a user hint" type="submit" value="Reset Form">

-- select_tag(name, options, attrs={})

Creates a <select..> tag (dropdown menu), including the various select options.

Note! the format for the options values must be [value, key].

Passing options values as a Hash.

select_tag(:letters, {a: 'A', b: 'B' })
  #  <select id="letters" name="letters">
  #   <option value="a">A</option>
  #   <option value="b">B</option>
  #  </select>

Passing options values as an Array.

@letters = [[:a,'A'], [:b,'B']]

select_tag(:letters, @letters)
  #  <select id="letters" name="letters">
  #    <option value="a">A</option>
  #    <option value="b">B</option>
  #  </select>

Handling passed options:

select_tag(:letters, @letters, disabled: true)
  #  <select id="letters" disabled="disabled" name="letters">
  #    <snip...>

select_tag(:letters, @letters, id: 'my-letters')
  #  <select id="my-letters" name="letters">
  #    <snip...>

select_tag(:letters, @letters, class: 'funky-select')
  #  <select class="funky-select" id="my-letters" name="letters">
  #    <snip...>

Handling the prompt value:

select_tag(:letters, @letters, prompt: true)
   #  <select id="letters" name="letters">
   #    <option selected="selected" value="">- Select -</option>
   #    <snip...>

 # setting a custom prompt
select_tag(:letters, @letters, prompt: 'Top Letters', selected: 'a')
   #  <select id="letters" name="letters">
   #    <option value="">Top Letters</option>
   #    <option selected="selected" value="a">A</option>
   #    <snip...>

Adding :selected option.

select_tag(:letters, @letters, selected: :a)
  #  <select id="letters" name="letters">
  #    <option selected="selected" value="a">A</option>
  #    <snip...>

When passing multiple items to :selected option or setting the { multiple: true } option, the select menu automatically becomes a multiple select box.

NOTE! the name="letters[]" attribute.

select_tag(:letters, @letters, selected: [:a,'b'])
  #  <select id="letters" multiple="multiple" name="letters[]">
  #    <option selected="selected" value="a">A</option>
  #    <option selected="selected" value="b">B</option>
  #  </select>

select_tag(:letters, @letters, multiple: true)
  #  <select id="letters" name="letters[]" multiple="multiple">
  #    <snip...>

-- select_option(value, key, attrs={})

Creates an <option...> tag for <select...> menus.

select_option('a', 'Letter A')
  #=> <option value="a">Letter A</option>

select_option('on', '')  # , nil)
  #=> <option value="on">On</option>

 # handling selected options
select_option('a', 'Letter A', selected: true)
  #=> <option selected="selected" value="a">Letter A</option>

select_option('a', 'Letter A', selected: false)
  #=> <option value="a">Letter A</option>

-- faux_method(method='PUT')

 faux_method() #=> <input name="_method" type="hidden" value="PUT">

 # handling DELETE requests
 faux_method(:delete) #=> <input name="_method" type="hidden" value="DELETE">

Plugin Configurations

The default settings should help you get moving quickly, and are fairly common sense based.

However the :tags plugin supports these config options:

:tag_output_format_is_xhtml

Sets the HTML output format, toggling between HTML 5 (false) and XHTML (true). Default is: false.

This option is retained for legacy support and in memory of the "good old days" ;-).

:tag_add_newlines_after_tags

Sets the formatting of the HTML output, whether it should be more compact in nature or slightly better formatted. Default is: true.

The :tag_helpers plugin supports these config options:

:tags_label_required_str

Sets the formatting of the string appended to required <label...> tags. Default is: '<span>*</span>'.

:tags_label_append_str

Sets the formatting of the string appended to <label...> tags. Default is: ':'.

:tags_forms_default_class

Sets the default class value for form tags. Default is: '' (empty).

This is a shortcut to automatically add something like Bootstrap support with 'form-control'

NOTE!

Config options set in :tag_helpers are passed on to the :tags plugin.

 # <snip...>
 # support legacy XHTML formatted output
plugin :tag_helpers, { tag_output_format_is_xhtml: true, ... }
 # <snip...>

RTFM

If the above is not clear enough, please check the specs for a better understanding.

Errors / Bugs

If something is not behaving intuitively, it is a bug, and should be reported. Report Issues here


TODOs

  • Keep it up to date with any changes in Roda or HTML.

  • Decide on if it's worth it to do validity checks on all attributes passed to tags ie: reject attributes based upon what is allowed for the tag.

    tag(:base, href: 'url', target: '_self', id: 'is-ignored')
      #=> <base href="url", target="_self">
  • Decide on whether to add a number of convenience tags (methods), such as:

    • meta(name, contents)
    • img(src, attrs={})
  • Any other improvements we may think of.


Acknowledgements

Inspiration for this gem was taken from the ActiveSupport gem by DHH & Rails Core Team released under the MIT license.


Development

After checking out the repo, run bundle install to install dependencies. Then, run bundle exec rake spec to run the tests.

To install this gem onto your local machine, run bundle exec rake install.

To release a new version:

  1. update the version number in version.rb
  2. run bundle exec rake release, which will create a git tag for the version
  3. push git commits and tags
  4. push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub.

This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Copyright

Copyright (c) 2010 - 2024 Kematzy

Released under the MIT License. See LICENSE for further details.

License

The gem is available as open source under the terms of the MIT License.