0.02
A long-lived project that still receives updates
Markdown Rails is a comprehensive stack for rendering Markdown templates and partials in Rails.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

>= 3.0.0
>= 6.0.0
>= 6.0.0
 Project Readme

markdown-rails

This gem allows you to write static Rails views and partials using the Markdown syntax. No more editing prose in HTML!

It is a comprehensive Markdown library for Rails that addresses the following pain points:

  • Renders markdown files and partials that you can throw in your Rails view paths, like ./app/views/people/profile.html.md.
  • Parse Erb blocks in markdown files.
  • Customize markdown tags like ![]() to support embeds beyond images like YouTube links, code fences for syntax highlighting, etc.
  • Plug into Rails asset pipeline so images defined in Markdown will be loaded from the forever-cached image assets.
  • Define multiple markdown renders so you can render more dangerous-user upload markdown content vs markdown that you can trust, like content files checked into your Rails project.

This project is used heavily by https://sitepress.cc to manage content files in Rails, but it can be used on its own for Rails views.

Usage

Add the following to your application's Gemfile:

$ bundle add 'markdown-rails'

Then from the root of your Rails project, run:

$ bin/rails g markdown_rails:install

This adds a config/initializers/markdown.rb file where you can register template handler for your Markdown renders that are located in ./app/markdown/*.rb.

Now add views or partials ending in .md in your ./app/views/**/** directories and behold!

Upgrading from 1.x

Change your applications Gemfile to read:

gem "markdown-rails", "~> 2.0.0"

Then from the root of your Rails project, run:

$ bin/rails g markdown_rails:install

If you have an existing file in config/initializers/markdown.rb you'll need to move those settings over. Note that 1.x used RDiscount as the default renderer, which was replaced by Redcarpet in 2.x.

Configuration

Applications commonly need various markdown variants within one application. For example,

# ./config/initializers/markdown.rb
# Restart the server to see changes made to this file.

# Setup markdown stacks to work with different template handler in Rails.
MarkdownRails.handle :md do
  ApplicationMarkdown.new
end

MarkdownRails.handle :crazymd do
  MyCrazyMarkdown.new
end

Enable Erb in Markdown

Only enable Erb in Markdown if you trust the source of the file. Do not enable it for markdown provided by users or they will be able to execute arbitrary Ruby code.

# ./config/initializers/markdown.rb
MarkdownRails.handle :markerb do
  ErbMarkdown.new
end

You could change :markerb to :md, but I don't recommend it for all Markdown files or you'll run into problems if you have content like <%= Time.current %> inside of an erb codefence. You're better off having two configurations: one that handles Erb and another that doesn't, like this:

# ./config/initializers/markdown.rb
# Restart the server to see changes made to this file.

# Setup markdown stacks to work with different template handler in Rails.
MarkdownRails.handle :md do
  ApplicationMarkdown.new
end

MarkdownRails.handle :markerb do
  ErbMarkdown.new
end

The same technique can be used for preprocessing Markdown with other handlers, like liquid.

Customizing renderer

You might want to customize your Markdown handler to do things like syntax code highlighting, etc.

# ./app/markdown/application_markdown.rb
require "rouge"

class ApplicationMarkdown < RailsMarkdown
  include Redcarpet::Render::SmartyPants

  FORMATTER = Rouge::Formatters::HTMLInline.new("monokai.sublime")

  def enable
    [:fenced_code_blocks]
  end

  def block_code(code, language)
    lexer = Rouge::Lexer.find(language)
    content_tag :pre, class: language do
      raw FORMATTER.format(lexer.lex(code))
    end
  end
end

Consider using a componet farmework, like phlex to generate tags outside of the Rails view context.

Examples

There's a lot of ways to use Markdown in your Rails app.

The easy way

Your best bet is to use this with a content management site like https://sitepress.cc/ if you're going to be dealing with a lot of markdown content on your website.

Static view

In app/views/home/about.html.md:

# About This Site

*Markdown code goes here ...*

Keep in mind that unlike static files dropped in public, you still need a matching route, such as get ':action', :controller => :home, to route /about to home#about. You could also use Sitepress to automatically manage these routes for you if you're dealing with a lot of pages.

Static partial

In app/views/posts/edit.html.erb:

<form>... dynamic code goes here ...</form>
<div class="help">
  <%= render :partial => "posts/edit_help" %>
</div>

In app/views/posts/_edit_help.html.md:

## How To Edit

This text is written in **Markdown**. :-)

Note: If you are including Markdown partials from a Haml view, <pre> blocks inside your Markdown may be indented when Haml is not in "ugly" (production) mode, causing leading white-space to appear in development mode. To fix this, set Haml::Template.options[:ugly] = true.

Security

Despite Markdown being a static language, you should not use this gem to process untrusted Markdown views (or partials). In other words, do not add Markdown views from a source if you wouldn't trust Erb views from them.