MarkupAttributes
A simple Rails engine for cleanly handling Textile/Markdown markup in ActiveRecord attributes.
Using this engine, we can define a particular attribute as containing markup, with constraints around which markup rules and tags we want to support, and then render that attribute value to HTML consistently throughout the rest of the application.
Rather than adding any HTML generation into the model itself, this works by attaching metadata to the model, which can then be consumed by a helper when the attribute is used in views.
In the future, this will expand to also handle Markdown, Github-Flavoured Markdown and potentially any other markup language; the underlying mechanism is markup-agnostic, and others can easily be added.
Usage
Once you've added this gem to your application, you can enable it on a per-model basis by extending the model class with the {#MarkupAttributes} module, and then declaring one or more attributes as having textile:
class Post < ApplicationRecord
extend MarkupAttributes
textile_attribute :title, :description
end
You can then deal with the model as with any other ActiveRecord subclass; the attributes can be treated as simple strings:
post = Post.create(title: 'My _cool_ post', description: 'A post about *stuff*')
post.title # => 'My _cool_ post'
post.description # => 'A post about *stuff*'
When you want to render the markup in a view, use the render_markup
helper method:
<h1><%= render_markup post.title %></h1>
<p><%= render_markup post.description %></p>
which will produce the HTML
<h1>My <em>cool</em> post</h1>
<p>A post about <strong>stuff</strong></p>
Markup constraints
The main benefit of this gem is that it allows you to define constraints about what markup
an attribute should support in a single place, and have those rules be applied consistently
wherever the content is rendered. We do this using the :allow
and :deny
options to
textile_attribute
.
class Post < ApplicationRecord
extend MarkupAttributes
textile_attribute :title, allow: :emphasis
end
If any :allow
options are set, anything missing from that option is assumed to be denied, and
will be removed from the rendered markup. So, anywhere we try to render the title markup now,
these rules will be respected:
<% post = Post.new(title: '"Link":http://example.com this _up_') %>
<%= render_markup post.title %>
produces
Link this <em>up</em>
Because we didn't allow links, that aspect of the markup is removed.
We can include multiple allowed markup types:
textile_attribute :title, allow: [:emphasis, :links, :images]
or, we can allow all markup and then explicitly deny certain types:
textile_attribute :title, deny: :images
Installation
Add this line to your application's Gemfile:
gem 'markup_attributes'
And then execute:
$ bundle
Or install it yourself as:
$ gem install markup_attributes
Contributing
Contribution directions go here.
License
The gem is available as open source under the terms of the MIT License.