Open Source ProjectsCode that Might be Useful to You

Talks I've GivenOn Technologies and Ideas

ThoughtsWhere I Sometimes Write Things

Resume If You Believe In Those

Follow Me On

GitHubIf coding is your thing

TwitterIf you tweet

Manage your markup with has_markup

I recently decided to extract some plugins, in an effort to clean up the codebase for my blog.

The first thing I tackled was generation of HTML from my Post model.

In the beginning…

Here’s the starting point for my model:

class Post < ActiveRecord::Base
  # --- SNIP ---

  # TODO move into own file... and plugin?
  def self.validates_markdown(*attrs)
    validates_each(*attrs) do |record, attr, value|
      begin unless value.nil?
      rescue BlueCloth::FormatError => e
        errors.add attr, "has #{e}"
  validates_presence_of :content
  validates_markdown :content
  before_save :cache_content

  # Use BlueCloth to generate HTML ahead of time.
  def cache_content
    html =
    self.cached_content = html

  # --- SNIP ---

validates_markdown really doesn’t belong here, and nothing interesting is happening, but the lines of code start to add up.

Let’s look at the partial for Post.

%div{ :id => dom_id(post), :class => dom_class(post) }
  %h2.title= link_to(post.title, post)
  .content~ post.cached_content

Eh, nothing particuarly interesting.


  • One-liner for specifying markup, similar to has_many or acts_as_taggable
  • Optionally require the markup
  • Optionally cache the markup
  • Allow for different syntaxes

A whole new look on things

I was able to extract the logic out of my model and hit all of these goals.

The refactored model:

class Post < ActiveRecord::Base
  # --- SNIP ---

  has_markup :content, :required => true, :cache_html => true

  # --- SNIP ---

And the view is more or less the same:

%div{ :id => dom_id(post), :class => dom_class(post) }
  %h2.title= link_to(post.title, post)
  .content~ post.cached_content_html


  • Plugins are really easy to make
  • Plugins can pull a good amount of code out of your model, which results in it being more readable
  • I think I finally understand the difference between include and extend

Get it

If you’re interested in trying this plugin, it is hosted on GitHub. You can install it by with:

script/plugin install git:// 
comments powered by Disqus