Rails markdown to html

Using Markdown for Static Pages in Rails

Markdown is great for formatting our writing to be publish as HTML. If you’re a developer, you probably used Markdown before. README of GitHub repositories are mostly written in Markdown.

While developing web applications, there will be static pages such as about page and FAQ page. Most of the time, we have to write it in HTML, which can be unpleasant.

Luckily, we can still use Markdown to write the static pages in Rails application and compile it into HTML.

General Steps

The steps involved are straightforward.

  1. Write Markdown
  2. Compile the Markdown
  3. Rails use the compiled HTML to serve the user.
  1. Compile the Markdown file on runtime, which means, the file is only compiled when there is a request.
  2. Precompile the Markdown file into .html.erb first.

Compilation of Markdown during runtime

To compile a Markdown file during runtime in Rails, we need to know how to:

  • Compile Markdown file in ruby
  • Render the compiled HTML as views
  • Bind ERB environment if instance variables @variable is used in the view

To compile a Markdown file is fairly straighforward in ruby :

# gem install kramdown if not found require 'kramdown' file = File.read('about.md') html = Kramdown::Document.new(file, input: "GFM">).to_html # Configuring to set kramdown to use GFM parser # instead of the defaut one. GFM parser can parse Github Flavour Markdown. p html #=> .  

To use it in a Rails application:

gem 'kramdown', require: false # require: false since we are going to require it only # when we need it 

In the app/views/pages/about.md :

In the app/views/pages/about.html.erb :

 raw @content %> # We want the raw output of the @content instead of escaped 

In the app/controllers/pages_controller.rb :

require 'kramdown' class PagesController  ApplicationController def about file_path = lookup_context.find_template("#controller_path>/#action_name>") .identifier.sub(".html.erb", ".md") @name = "Kai" # Compiled with ERB result = ERB.new( File.read(file_path) ).result(binding) # Convert MD to HTML @content = Kramdown::Document.new(result, input: "GFM">).to_html end end 

All the views file are self-explanatory, so let’s just focus on the controller.

First of all, we need to get the md file in our controller. We can achieive it by hardcoding it like file_path = «../views/pages/about.md» . But it is better to make it dynamically look up the right md file depending on the action of the controller.

template = lookup_context.find_template("#controller_path>/#action_name>") #=> app/views/pages/about.html.erb template.identifier #=> "/Users/. /app/views/pages/about.html.erb" template.identifier.sub(".html.erb", ".md") #=> "/Users/. /app/views/pages/about.md" 

How I know I should use this method to lookup for the file? Google search leads me to this Stackoverflow question and answer.

After that, we need to compile the md file first with ERB since we are erb syntax. After that, we just need to convert the result to HTML using kramdown .

The benefit of this approach is:

  • Don’t need to manually compile the md files.
  • Can be used to compile dynamic Markdown files.

Precompile the Markdown file

Another approach, is more troublesome, but has less overhead, since the server don’t need to recompile the same Markdown file everytime someone visit to the page.

Instead of compile during runtime, we compile manually everytime after we update our Markdown file. Rails just serve the .html.erb that we converted from the Markdown files to the visitors.

To do that, we can write a rake task. Add the following code into your Rakefile .

# Get all files in /app/views/page ending with md SOURCE_FILES = Rake::FileList.new("app/views/pages/*md") # Define a task task :compile_md => SOURCE_FILES.pathmap("%X.html.erb") # Define rule for the task rule '.html.erb' => SOURCE_FILES do |t| require 'kramdown' content = Kramdown::Document.new(File.read(t.source), input: "GFM">).to_html File.write(t.name, content) end 

This code block is a bit tricky. To summarize, what it does is scan through all the .md files located in /app/views/page and compile it into .html.erb if any changes is made.

We can then run rake compile_md to manually compile our Markdown file into erb file after we updated our Markdown file.

With this approach, do note that we did not handle erb syntax. Hence, there is a gotcha. If you need to use erb syntax, you need to write plain html instead. To demonstrate:

### Hello This is my first sentence. Total view:   

The benefits of this approach is:

Summary

That’s all. I know there are a lot of magic happening on the rake task I wrote above.

To further understand the rake task, I would suggest these tutorials from Avdi Grimm’s rake series as suggested in rake README:

A sample application for this post can be found at my Github.

  1. I am sorry if this post is a bit messy. I am still not quite good at writing and structuring lengthy tutorial.

Источник

Markdown разметка в RubyOnRails-приложении

В одном новом проекте, написанном на ruby on rails, была поставлена задача дать возможность пользователю использовать markdown-разметку для форматирования текста. Один из вариантов реализации описан в данной статье.

Статья не описывает основы ruby on rails. Я подразумеваю, что читатель может создать проект и запустить его в своей любимой IDE / из консоли / еще как. Плюс в конце статьи есть ссылка на исходники демонстрационного проекта.
Одно уточнение: я использую haml для view-шек и twitter bootstrap для оформления.
Допустим что у нас есть приложение. И нам надо добавить в него класс «Статья» с полями заголовок и содержимое. Поле содержимое будет типа text. К нему то нам и необходимо применить markdown-разметку.

Добавим наш класс и заодно контроллер и view-шки

rails generate scaffold Post title content:text rake db:migrate 

Markdown парсер

# app/helpers/application_helper.rb module ApplicationHelper def markdown(text) renderer = Redcarpet::Render::HTML.new(hard_wrap: true, filter_html: true) options = < autolink: true, no_intra_emphasis: true, fenced_code_blocks: true, lax_html_blocks: true, strikethrough: true, superscript: true, space_after_headers: true >Redcarpet::Markdown.new(renderer, options).render(text).html_safe end end 

Redcarpet::Markdown — сам markdown-парсер. Redcarpet::Render::HTML — один из рендереров. Конкретно этот генерирует html из markdown разметки. При желании можно написать свой рендерер или унаследовать от существующих. Возможные значения опций для рендерера и парсера можно посмотреть в документации.

Применяем helper для отображения содержимого

-# app/views/posts/show.html.haml %h3= @post.title %p= markdown(@post.content) = link_to 'Edit', edit_post_path(@post) \| = link_to 'Back', posts_path 
> this is quotes List: - item 1 - item 2 - item 3 [this is link](http://example.com) ![image](http://placehold.it/350x150) ``` class Cat < Animal def say "Meow!" end end ``` 

то увидим примерно следующую картину

Markdown редактор

# Gemfile . gem 'markitup-rails' 
# app/assets/javascripts/application.js … //= require markitup …
// app/assets/stylesheets/application.css.scss … @import "markitup"; @import "markitup-markdown";
# app/assets/javascripts/posts.js.coffee jQuery -> markdownSettings = < previewParserPath: '/markdown/preview' onShiftEnter: markupSet: [ < name:'First Level Heading', key:'1', placeHolder:'Your title here. ', closeWith: (markItUp) ->markdownTitle(markItUp, '=') >, < name:'Second Level Heading', key:'2', placeHolder:'Your title here. ', closeWith: (markItUp) ->markdownTitle(markItUp, '-') >,          markItUp.line+'. ' > < name:'Picture', key:'P', replaceWith:'![[![Alternative text]!]]([![Url. http://]!] "[![Title]!]")' >, < name:'Link', key:'L', openWith:'[', closeWith:']([![Url. http://]!] "[![Title]!]")', placeHolder:'Your text to link here. ' >,  '>   ] > markdownTitle = (markItUp, char) -> heading = ''; n = $.trim(markItUp.selection||markItUp.placeHolder).length; for i in [0..n] heading += char '\n'+heading $('#post_content').markItUp(markdownSettings) 

где post_content — id текстового поля. Настройки редактора (markdownSettings) взяты из документации.
И теперь форма редактирования выглядит примерно так

Предварительный просмотр

# app/assets/javascripts/posts.js.coffee . previewParserPath: '/markdown/preview' 
# app/controllers/markdown_controller.rb class MarkdownController < ApplicationController def preview @text = params[:data] end end 
-# app/views/markdown/preview.html.haml = markdown(@text)
# config/routes.rb . post "markdown/preview" 

И теперь у нас есть работающее превью (с указанными выше настройками вызывается последней кнопкой на панели редактора)

  • Markdown
  • Redcarpet
  • MarkItUp
  • Исходники проекта из данной статьи
  • Наш новый проект, где можно посмотреть реальное применение описанного в статье алгоритма

Источник

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

dvxam/rails_markdown_to_html

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.textile

This application was generated with the rails_apps_composer gem provided by the RailsApps Project.

This application was built with recipes that are NOT known to work together.

This application was built with preferences that are NOT known to work together.

If the application doesn’t work as expected, please report an issue and include these diagnostics:

We’d also like to know if you’ve found combinations of recipes or preferences that do work together.

Recipes:
[“apps4”, “controllers”, “core”, “email”, “extras”, “frontend”, “gems”, “git”, “init”, “models”, “prelaunch”, “railsapps”, “readme”, “routes”, “saas”, “setup”, “testing”, “views”]

Preferences:
true, :railsapps=>"none", :dev_webserver=>"webrick", :prod_webserver=>"same", :database=>"mongodb", :orm=>"mongoid", :templates=>"erb", :unit_test=>"test_unit", :integration=>"none", :continuous_testing=>"none", :fixtures=>"none", :frontend=>"bootstrap", :bootstrap=>"sass", :email=>"none", :authentication=>"none", :authorization=>"none", :form_builder=>"none", :starter_app=>"none", :rvmrc=>false, :local_env_file=>true, :better_errors=>true, :ban_spiders=>true, :github=>true>

This application requires:

This application uses MongoDB with the Mongoid ORM .

  • Template Engine: ERB
  • Testing Framework: Test::Unit
  • Front-end Framework: Twitter Bootstrap (Sass)
  • Form Builder: None
  • Authentication: None
  • Authorization: None

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Documentation and Support

This is the only documentation.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

If you make improvements to this application, please share with others.

  • Fork the project on GitHub.
  • Make your feature addition or bug fix.
  • Commit with Git.
  • Send the author a pull request.

If you add functionality to this application, create an alternative implementation, or build an application that is similar, please contact me and I’ll add a note to the README so that others can find your work.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Источник

Читайте также:  This is demo site
Оцените статью