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.
Once you've added this gem to your application, you can enable it on a per-model basis by extending the model class with themodule, and then declaring one or more attributes as having textile:
class Post < ApplicationRecord extend 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>
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
:deny options to
class Post < ApplicationRecord extend textile_attribute :title, allow: :emphasis end
: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 %>
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
Add this line to your application's Gemfile:
And then execute:
Or install it yourself as:
$ gem install markup_attributes
Contribution directions go here.
The gem is available as open source under the terms of the MIT License.