at.
at.

Reputation: 52500

Using Markdown with Rails

I want users to type in Markdown text in a textarea and when they post it, I display the corresponding html. I read that Rails used to have a markdown method or similarly called method, that you could just call on that field in the ERB file:

<%= markdown(@post.content) %>

Apparently, Rails took that functionality out. What is the best way to get that functionality again? That seems to solve my need.

Upvotes: 16

Views: 8257

Answers (3)

fguillen
fguillen

Reputation: 38772

This is my solution

Gemfile

gem "redcarpet"

config/initializers/markdown_renderer.rb

module MarkdownRenderer
  def self.markdown
    @@markdown ||=
      Redcarpet::Markdown.new(
        Redcarpet::Render::HTML.new(
          escape_html: true,
          hard_wrap: true,
          safe_links_only: true,
          with_toc_data: true
        ),
        autolink: true,
        fenced_code_blocks: true,
        no_intra_emphasis: true,
        space_after_headers: true,
        tables: true
      )
  end

  def self.render(text)
    markdown.render(text)
  end
end

app/helpers/application_helper.rb

def markdown(text)
  MarkdownRenderer.render(text).html_safe
end

your view

<%= markdown(@post.content) %>

Upvotes: 5

ytbryan
ytbryan

Reputation: 2694

The solution provided had been turned into a gem emd. You can read more here

Add these lines to your application's Gemfile:

gem 'coderay' #optional for Syntax Highlighting
gem 'redcarpet'
gem 'emd'

And then execute:

bundle

To create markdown partial, view or enable syntax highlighting on code block, visit the usage of emd

Upvotes: 1

Jiř&#237; Posp&#237;šil
Jiř&#237; Posp&#237;šil

Reputation: 14401

I would use Redcarpet to do the markdown-html conversion. Also, I would move the conversion from the view to some other object. You could use callbacks (before_save) or use Observers.

From the docs:

markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML,
    :autolink => true, :space_after_headers => true)

markdown.render("This is *bongos*, indeed.")
#=> "<p>This is <em>bongos</em>, indeed</p>"

You probably want to store the result in another column, say @post.content_parsed so that the user can make later edits to the post, plus this way you don't need to make the conversion on every request.

Upvotes: 23

Related Questions