11 February 2021

Movable Type TinyMCE5エディターの書式設定ボタンをカスタマイズする

Movable Type 6のTinyMCE5プラグインで表示されるエディターの書式設定ボタンをカスタマイズする方法

20210211-tinimce-editribbon.jpg
赤線で囲ったところが書式設定ボタン

20210211-tinimce-plugin.jpg
TinyMCE5プラグインだけを有効に設定する

この記事で扱っているMovable Typeのバージョンは 6.7.5 で、GitHubの movabletype/movabletype - Releases からダウンロードしたものを使っている。

編集リボンに表示するボタンを定義する部分を書き換える

ここで説明する設定ファイル 20210211_movabletype_tinymce_cust_js.zipをダウンロードする

初期状態ではリボンは1行(plugin_mt_source_buttons1)だが、2行目(plugin_mt_source_buttons2)を新たに追加した。

mt6/mt-static/plugins/TinyMCE5/lib/js/adapter.js の43行目あたり
$.extend(MT.Editor.TinyMCE, MT.Editor, {
    isMobileOSWYSIWYGSupported: function() {
        return false;
    },
    config: {
 
        // Buttons using in source mode.
        plugin_mt_source_buttons1: 'mt_source_ex_b mt_source_italic mt_source_blockquote mt_source_unordered_list mt_source_ordered_list mt_source_list_item mt_source_ex_a mt_source_link mt_insert_file mt_insert_image',
        plugin_mt_source_buttons2: 'mt_source_ex_code mt_source_ex_pre mt_source_ex_ruby mt_source_ex_stylefont mt_source_ex_stylecolor mt_source_ex_styleline mt_source_ex_indent mt_source_ex_indent_minus mt_source_ex_indent_block mt_fullscreen',

次に、このボタン名が指し示すボタン定義部分をmt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/plugin.jsに記述していく。

ボタンの見た目を定義する部分を追加・編集する

新たなボタンを追加した部分のソースコード追加は次のようなものになる。

"text" はリボンに表示するボタン名文字列を直接記載し、"tooltip" は文字列を格納しているリソース変数を指定する。

onclickFunctionsの"source"には、ボタンを押したときの機能を定義しているmt-static/js/editor/editor_command/source.js内の関数名を指定する。

mt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/plugin.js  640行目あたりから追加
;(function($) {
 
    tinymce.create('tinymce.plugins.MovableType', {
  
        init : function(ed, url) {
 
            /* ~ 省略 ~ */

            ed.addMTButton('mt_source_mode', {
                icon : 'sourcecode',
                tooltip : 'source_mode',
                toggle: true,
                onclickFunctions : {
                    wysiwyg: function() {
                        ed.execCommand('mtSetFormat', 'none.tinymce_temp');
                    },
                    source: function() {
                        ed.execCommand('mtSetFormat', 'richtext');
                    }
                },
                onSetup: function(buttonApi) {
                    ed.on('mtChangeFormat', function(){
                        var s = ed.mtEditorStatus;
                        buttonApi.setActive( s.mode && s.mode == 'source');
                    });
                }
            });
 
            ed.addMTButton('mt_source_ex_b', {
                tooltip : 'source_ex_b',
                text : '<b>',         /* <,> はエスケープして記述する */
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExB'
                }
            });

            ed.addMTButton('mt_source_ex_code', {
                tooltip : 'source_ex_code',
                text : '<code>',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExCode'
                }
            });

            ed.addMTButton('mt_source_ex_pre', {
                tooltip : 'source_ex_pre',
                text : '<pre>',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExPre'
                }
            });

            ed.addMTButton('mt_source_ex_stylefont', {
                tooltip : 'source_ex_stylefont',
                text : 'Font ',         /* リソースの自動置換で「日本語」に変換されないために、末尾にスペース1個入れている */
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExStyleFont'
                }
            });

            ed.addMTButton('mt_source_ex_stylecolor', {
                tooltip : 'source_ex_stylecolor',
                text : 'Color ',        /* リソースの自動置換で「日本語」に変換されないために、末尾にスペース1個入れている */
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExStyleColor'
                }
            });

            ed.addMTButton('mt_source_ex_styleline', {
                tooltip : 'source_ex_styleline',
                text : 'Line',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExStyleLine'
                }
            });

            ed.addMTButton('mt_source_ex_ruby', {
                tooltip : 'source_ex_ruby',
                text : '<ruby>',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExRuby'
                }
            });

            ed.addMTButton('mt_source_ex_indent', {
                tooltip : 'source_ex_indent',
                text : '字下',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExIndent'
                }
            });

            ed.addMTButton('mt_source_ex_indent_minus', {
                tooltip : 'source_ex_indent_minus',
                text : '字上',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExIndentMinus'
                }
            });

            ed.addMTButton('mt_source_ex_indent_block', {
                tooltip : 'source_ex_indent_block',
                text : 'indent',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExIndentBlock'
                }
            });

            ed.addMTButton('mt_source_ex_a', {
                tooltip : 'source_ex_a',
                text : '<a>',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'ExA'
                }
            });

なお、ボタンの表示を変更した部分もあり、

mt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/plugin.js  540行目あたりから580行目あたりまで
            ed.addMTButton('mt_source_italic', {
                tooltip : 'source_italic',
                text : '&lt;em&gt;',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'italic'
                }
            });
 
            ed.addMTButton('mt_source_blockquote', {
                tooltip : 'source_blockquote',
                text : '&lt;blockquote&gt;',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'blockquote'
                }
            });
 
            ed.addMTButton('mt_source_unordered_list', {
                tooltip : 'source_unordered_list',
                text : '&lt;ul&gt;',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'insertUnorderedList'
                }
            });
 
            ed.addMTButton('mt_source_ordered_list', {
                tooltip : 'source_ordered_list',
                text : '&lt;ol&gt;',
                mtButtonClass: 'text',
                toggle: true,
                onclickFunctions : {
                    source: 'insertOrderedList'
                }
            });
 
            ed.addMTButton('mt_source_list_item', {
                tooltip : 'source_list_item',
                text : '&lt;li&gt;',
                mtButtonClass: 'text',
                onclickFunctions : {
                    source: 'insertListItem'
                }
            });

ボタンのツールチップ文字列を定義するリソースを追加

mt-static/plugins/TinyMCE5/lib/js/tinymce/plugins/mt/langs/plugin.js
    // HTML mode
    "source_bold": trans('太字タグ'),
    "source_italic": trans('斜体タグ'),
    "source_blockquote": trans('blockquote 引用記事セクションHTMLタグ'),
    "source_unordered_list": trans('箇条書き(ナンバリング無し)'),
    "source_ordered_list": trans('箇条書き(ナンバリングあり)'),
    "source_list_item": trans('箇条書きのアイテム'),
 
    "source_ex_b": trans('太字タグ'),
    "source_ex_code": trans('codeタグ'),
    "source_ex_pre": trans('preセクションHTMLタグ'),
    "source_ex_stylefont": trans('斜体・太文字・文字サイズ CSS'),
    "source_ex_stylecolor": trans('テキスト色 CSS'),
    "source_ex_styleline": trans('中線・下線 CSS'),
    "source_ex_ruby": trans('ルビ'),
    "source_ex_indent": trans('行頭を1字下げ CSS'),
    "source_ex_indent_minus": trans('行頭を1字上げ CSS'),
    "source_ex_indent_block": trans('インデント CSS'),
    "source_ex_a": trans('A Linkタグ'),

ボタンを押したときの機能を定義する

mt-static/js/editor/editor_command/source.js
MT.EditorCommand.Source.prototype.commands['default'] = {
 
    ExB: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<b>', '</b>', text);
    },

    ExCode: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<code>', '</code>', text);
    },

    ExPre: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<pre class="title">ソースコード</pre><pre>', '</pre>', text);
    },

    ExStyleFont: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<span style="font-size:1.2em; font-style:italic; font-weight:bold; font-stretch:50%;">', '</span>', text);
    },

    ExStyleColor: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<span style="color:red; background-color:yellow; opacity:0.5;">', '</span>', text);
    },

    ExStyleLine: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<span style="text-decoration: dashed line-through underline red 1px;">', '</span>', text);
    },

    ExRuby: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<ruby>', '<rp>(</rp><rt>ふりがな</rt><rp>(</rp></ruby>', text);
    },

    ExIndent: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<div style="text-indent:1em;">', '</div>', text);
    },

    ExIndentMinus: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<div style="text-indent:-1em; padding-left:1em;">', '</div>', text);
    },

    ExIndentBlock: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<div style="margin-left:2em;">', '</div>', text);
    },

    ExA: function(command, userInterface, argument, text) {
        this.execEnclosingCommand(command, '<a href=\"\">', '</a>', text);
    },