Blog

Movable Typeの気づいた点などの紹介

2020.01.28

MTAppjQuery + Vue.js + Markdown-itで使ってMarkdown投稿を実装(記事版)

  • JavaScript
  • MTAppjQuery
  • Vuejs

前回の記事では、コンテンツタイプを行いました。
この記事では、記事でMarkdownを実装する方法になります。

注意:先に前回の記事で行った設定の部分にMarkdownを読み込ませる設定をしてください。

記事の場合

まずはコンテンツタイプと同様に記事に3つのカスタムフィールドを設定します。

  • MarkdownEditor:cf_markdowneditor(ベースネーム・カスタムフィールドタグ)
  • プレビューHTML:cf_preview_html(ベースネーム・カスタムフィールドタグ)
  • 保存用:cf_save_data(ベースネーム・カスタムフィールドタグ)

カスタムフィールドもコンテンツタイプ同様の理由で作っています。

コード

次に作成したフィールドを元に user.jsとuser.cssを作っていきます。
今回は記事に適用するため、記事画面のみ呼び出すように条件分岐を設定しておきます。

if((mtappVars.blog_id === 1) && mtappVars.screen_id === 'edit-entry'){
}

次にカスタムフィールドのIDを変数オブジェクトに格納します。
こちらもコンテンツタイプ同様に構成です。
カスタムフィールドは標準でIDを付与してくれますので、そのままIDを取得します。

    const customFieldTagId = {
      markdownEditorId: '#customfield_cf_markdowneditor-field',
      saveId: '#customfield_cf_save_data-field',
      previewId: '#customfield_cf_preview_html-field'
    }
    const customFieldMarkdownEditor = $(customFieldTagId.markdownEditorId + ' > div > .mt-draggable__content');
    const customFieldSaveData = $(customFieldTagId.saveId + ' textarea').val();
    const customFieldSaveDataTarget = $(customFieldTagId.saveId + ' textarea');
    const customFieldPreviewHtml = $(customFieldTagId.previewId + ' textarea');

コンテンツタイプ同様にappendします。

customFieldMarkdownEditor.append('<textarea class="form-control text high html5-form content-field markdown" v-model="text" @change="update"></textarea>');

Vue.js部分もコンテンツタイプ同様の構成でカスタムフィールドの textarea を呼び出します。

    const entryMarkdownEditor = new Vue({
      el: customFieldTagId.markdownEditorId,
      data: {
        text: customFieldSaveData
      },
      methods: {
        update: function () {
          this.$nextTick(function () {
            // 保存用のフィールドに入力データ格納
            customFieldSaveDataTarget.val(this.text);
            // 入力データをMarkdownに変換してプレビューHTMLへ代入
            const markup = md.render(this.text);
            customFieldPreviewHtml.val(markup)
          })
        }
      }
    });

全体コード

  if((mtappVars.blog_id === 1) && mtappVars.screen_id === 'edit-entry'){
    const customFieldTagId = {
      markdownEditorId: '#customfield_cf_markdowneditor-field',
      saveId: '#customfield_cf_save_data-field',
      previewId: '#customfield_cf_preview_html-field'
    }
    const customFieldMarkdownEditor = $(customFieldTagId.markdownEditorId + ' > div > .mt-draggable__content');
    const customFieldSaveData = $(customFieldTagId.saveId + ' textarea').val();
    const customFieldSaveDataTarget = $(customFieldTagId.saveId + ' textarea');
    customFieldMarkdownEditor.append('<textarea class="form-control text high html5-form content-field markdown" v-model="text" @change="update"></textarea>');
    const customFieldPreviewHtml = $(customFieldTagId.previewId + ' textarea');
    const entryMarkdownEditor = new Vue({
      el: customFieldTagId.markdownEditorId,
      data: {
        text: customFieldSaveData
      },
      methods: {
        update: function () {
          this.$nextTick(function () {
            // 保存用のフィールドに入力データ格納
            customFieldSaveDataTarget.val(this.text);
            // 入力データをMarkdownに変換してプレビューHTMLへ代入
            const markup = md.render(this.text);
            customFieldPreviewHtml.val(markup)
          })
        }
      }
    });
  }

CSSの調整

最後に入力に必要のないフィールドは外から見えないようにdisplay:noneをしつつプレビューHTMLは直接いじらせないように調整しましょう。

こちらはコンテンツタイプとは違いカスタムフィールドのIDに対して付与していきます。

#customfield_cf_markdowneditor {
  display: none;
}
#customfield_cf_preview_html-field textarea {
  height: 300px;
  pointer-events : none;
}
#customfield_cf_save_data-field {
  display: none;
}

最後に出力させるためのフィールドをテンプレートに記述して完了になります。

<mt:cf_preview_html />

プレビュー用のカスタムフィールドタグを呼び出すだけです。
不要になったEntryBodyも非表示にして良いですが、既存記事の兼ね合いから残しておきましょう。

これでコンテンツタイプと記事両方にMarkdownを適用できるので、標準Markdownに困ってる方は参考にしてみてください。

※絵文字などは途中までできたんですが、状態保存でエラーが出たのでこちらは調査してまた記事をアップデートできればと思います。

  • Facebook
  • Twitter
  • はてなブックマーク
CATEGORY BACK