2
3

More than 3 years have passed since last update.

Rails でmarkdownを実装

Posted at

はじめに

今回はメモアプリを開発しているのですがメモの投稿をmarkdownで実装したいと思い今回はその方法について学習していきます。

今回欲しかった機能
・markdown
・リアルタイムプレビュー

gemの導入

gem 'redcarpet', '~> 2.3.0'
gem 'coderay'
bundle install

マークダウン記法の実装

app/heplers/markdown_helper.rb
上記のファイルのところにmarkdown_helper.rbのファイルを新しく作成する。

markdown_helper.rb
module MarkdownHelper
  def markdown(explanation) #()内はカラム名を入れる
    options = {
    filter_html: true,
    hard_wrap: true,
    space_after_headers: true,
    with_toc_data: true
    }

    extensions = {
    autolink: true,
    no_intra_emphasis: true,
    fenced_code_blocks: true,
    tables: true
    }

    renderer = Redcarpet::Render::HTML.new(options)
    markdown = Redcarpet::Markdown.new(renderer, extensions)
    markdown.render(explanation).html_safe #()内にはカラム名
  end
end

optionsとextentionsの中身(filter_htmlとか)は参考サイトを参照してほしい。もっと丁寧に書いてあって参考になるはず。

リアルタイムプレビューの実装

まず、vue.jsとmarked.jsを読み込むように記述をする。

application.html.erb
<-- Vue.js読み込みの記述-->
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.10/vue.js'></script>
<--marked.js読み込みの記述-->
<script src='https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.js'></script>

viewの修正

new

_form.html.erb
<%= form_with model:note, local: true do |f| %>
  <div class='form-group'>
    <%= f.label :タイトル %>
    <%= f.text_field :title, class: 'form-control', id: 'note_title' %>
  </div>
  <div class='form-group'>
    <%= f.label :カテゴリー %>
    <%= f.collection_select :category_id, Category.all, :id, :name %>
  </div>
  <div class='form-group'>
    <div id='editor'>
      <%= f.label :内容 %>
      <%= f.text_area :explanation, rows: 5, class: 'form-control', id: 'note_explanation', "v-model" => "input", name: "note[explanation]" %>
    <div v-html='input | marked'></div>
  </div>
  <%= f.submit '登録', class: 'btn btn-success' %>
  </div>
  <% end %>

  <!-- リアルタイムプレビュー -->
  <script type="text/javascript">
    window.onload = function() {
      new Vue({
      el: '#editor',
      data: {
        input: '<%== j @note.explanation %>',
      },
      filters: {
      marked: marked,
      },
      });
    };
  </script>

上記のようになるのですが、部分的に解説をします。

<!-- リアルタイムプレビュー -->
  <script type="text/javascript">
    window.onload = function() {
      new Vue({
      el: '#editor',
      data: {
        input: '<%== j @note.explanation %>',   # 自分で設定したインスタンス変数とカラム名
      },
      filters: {
      marked: marked,
      },
      });
    };
  </script>

input: '<%== j @note.explanation %>'はeditの時にnote.explanationをフォームに入れるためです。

次に苦労したのが、form_withのf.text_areaにv-model inputを持たせてやる方法でした。v-というのが、Vue.js独特の記述らしく、Rubyタグの中で使うには

"v-model" => "input"

としてやる必要がありました。-で区切っているため、””なしで記述しても反応がありませんでした。

次にname属性です。

name: "note[explanation]" アプリ名[カラム名]

上記のように指定します。

最後に、text_areaに記述された部分が表示されるように記述をしてやる必要があります。

v-htmlもvue.jsの表現です。

ここでは、rubyタグではなく、HTMLタグ内の表記なので、このままで問題ありません。

show

私の場合、showアクションにマークダウン記法の記事を表示させたいと思っているので、それを修正する。

<div class='stretch-text'>
  <h2>タイトル:<%= @note.title %></h2>
  <h2>カテゴリ:<%= @note.category.name %></h2>
  <h2>説明:<%= markdown(@note.explanation) %></h2>   #ここを修正
  <%= link_to "編集する", edit_note_path(@note),data: {"turbolinks" => false} %>
  <%= link_to "削除", note_path(@note), method: :delete %>
</div>

変更点はmarkdown(“#{@note.explanation})としたところです。

こうすることで、マークダウン記法を読み取れるようになりました。

これで完成!

ここまで来れば実装できると思います。

最後に

説明不足のところや理解不足のところが多々ありますが分かり次第更新していこうと思います。
また、間違っていることろがあればご教授のほどよろしくお願いします。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3