WordPress TinyMCE ビジュアルエディタカスタマイズの例

More than 1 year has passed since last update.

2015.07.26 投稿

やることが多いのでコードベースで淡々とその方法を書きます。今回の要件は以下を想定

  • TinyMCE ビジュアルエディタに「テキストボックスを吐き出す」ボタンを追加
  • ボタンを押すとダイアログが開く
  • ダイアログはこんな感じ

スクリーンショット 2015-07-26 1.40.40.png

バージョン

  • WordPress 4.2.3

functions.php の編集

TinyMCE にオリジナルのボタンを追加するにあたっては、(WordPressではなく)TinyMCE のプラグインを作成する必要があるようです。ちなみにプラグインは js で作ります。

プラグインを WordPress に対応させるにあたってまずは、add_filter 'mce_buttons' でボタンを追加。add_filter 'mce_external_plugins' でプラグインとなる js を登録することになります。

functions.php
<?php

function register_button($buttons)
{
    $buttons[] = 'input_text';
    return $buttons;
}
add_filter('mce_buttons', 'register_button');

function mce_plugin($plugin_array)
{
    $plugin_array['custom_button_script'] = get_template_directory_uri() . '/editor_plugin.js';
    return $plugin_array;
}
add_filter('mce_external_plugins', 'mce_plugin');

?>

editor_plugin.js の編集

プラグインの追加と登録をする js の編集をするよ

editor_plugin.js
(function($, document, window){

    var path = $('#templateDirectory').val();

    tinymce.create(
        'tinymce.plugins.MyButtons',
        {
            init: function(ed, url)
            {
                ed.addButton(
                    'input_text',
                    {
                        title: 'input text',
                        image: path + '/path/to/image.png',
                        cmd: 'input_text_cmd'
                    }
                );

                ed.addCommand( 'input_text_cmd', function()
                {
                    ed.windowManager.open(
                    {
                        url: path + '/path/to/view.html',
                        width: 480,
                        height: 270,
                        title: 'テキストボックス名とラベル名をご入力ください'
                    },
                    {
                        custom_param: 1 
                    });
                });
            },
            createControl: function(n,cm)
            {
                return null;    
            }
        }
    );
    tinymce.PluginManager.add(
        'custom_button_script',
        tinymce.plugins.MyButtons
    );
})(jQuery, document, window);

この js での注目する点は、「addButton」「addCommand」の2つです。複数のボタンを同時に作る場合は先に挙げた functions.php の register_button で追加したいボタンを定義し、addButtonとaddCommand を追加したい分だけ羅列していきます。

またこの js の先頭で

var path = $('#templateDirectory').val();

とありますが、js からテーマディレクトリのパスを取得するためのコードです。そのために functions.php ではそのためのコードを用意しています。

function.php
function addHidden()
{
    $path = get_bloginfo( 'template_directory' );
    echo '<input type="hidden" id="templateDirectory" value='."{$path}".' />';
}
add_action('admin_menu', 'addHidden');

これで js からのパスの心配はなくなります。

ダイアログ画面の作成

View はこんな感じで。

view.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Input Component Name</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="../css/styles.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="../javascripts/common.js"></script>
</head>
<body id="innerBody">
<p>テキストボックス名・ラベル名をご入力ください。両項目とも必須となります。また、テキストボックス名は半角英数とアンダースコアのみを利用できます。</p>
<table id="tb_input">
    <tr>
        <td>テキストボックス名</td>
        <td><input type="text" id="ComponentName" class="form-control" /></td>
    </tr>
    <tr>
        <td>ラベル名</td>
        <td><input type="text" id="LavelName" class="form-control" /></td>
    </tr>
</table>
<p id="ui"><input type="button" id="cancel" class="btn btn-danger" value="Cancel" onclick="return false;" />&nbsp;<input type="button" class="btn btn-primary" id="submit" value="OK" onclick="return false;" /></p>
<div id="errText"></div>
</body>
</html>

スタイルはこんな感じで

@import "bootstrap-compass";
@import "bootstrap-variables";
@import "bootstrap";

#innerBody {
    padding: 10px;
    #tb_input {
        td {
            padding: 10px;  
        }
    }
    #errText {
        color: #FF0000;
        font-size: 0.8em;
    }
    #ui {
        text-align: center;
    }
}

最後に js はこんな感じです。

common.js
(function($, window, document, _){

    $(document).on('click','#submit',function(){
        $('#errText').empty();
        var nameValue = _.escape($('#ComponentName').val());
        var labelName = _.escape($('#LavelName').val());
        if(!(nameValue && labelName))
        {
            $('#errText').empty().text('テキストボックス名及びラベル名は必須です');
            return false;
        }

        if(!(/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(nameValue)))
        {
            $('#errText').empty().text('テキストボックス名に利用できる文字は半角英数字です。また先頭文字には数字を使うことができません');
            return false;
        }
        //var args = top.tinymce.activeEditor.windowManager.getParams();
        var inputTag = '<div id="inputTextDiv"><p><label for="'+ nameValue +'">'+labelName+'</label></p><p><input type="text" name="' + nameValue + '" id="' + nameValue + '" class="form-control"></p></div>';
        top.tinymce.activeEditor.selection.setContent(inputTag);
        top.tinymce.activeEditor.windowManager.close();
        return false;
    });

    $(document).on('click','#cancel',function(){
        $('#ComponentName').val('');
        $('#LavelName').val('');
        $('#errText').empty();
        top.tinymce.activeEditor.windowManager.close();
        return false;
    });

})(jQuery, window, document, _);

注目すべきコードはこちら

top.tinymce.activeEditor.selection.setContent(inputTag);
top.tinymce.activeEditor.windowManager.close();

top.tinymce.activeEditor.selection.setContent() でアクティブになっているエディタの現在のカーソル位置に引数で渡した文字列が挿入されます。

top.tinymce.activeEditor.windowManager.close() でカスタムダイアログを閉じます。

最後に

ビジュアルエディタには以下のアイコンを用意

input.png

こんな感じで表示されます

スクリーンショット 2015-07-26 11.51.11.png

このアイコンは、editor_plugin.js の addButton() のパラメータでパスを指定してます。

ed.addButton(
    'input_text',
    {
        title: 'input text',
        image: path + '/inc/assets/images/input.png',
        cmd: 'input_text_cmd'
    }
);

実際にテキストボックスを追加してみます。まずはビジュアルエディタ側。

スクリーンショット 2015-07-26 12.14.40.png

HTMLはこんな感じになります。

スクリーンショット 2015-07-26 12.14.52.png
 
以上でカスタマイズの流れとなります。カスタムダイアログに関する情報が少なめだったので、TinyMCEの本家サイトでコードを漁りました。
 
慣れればカスタムのボタンをガンガン追加して、AddQuickTagなどのプラグインが無くてもよりインタラクティブなUIを提供できるようになります。
 

おまけ

ビジュアルエディタにオリジナルのCSSを適用させるには、functions.phpに以下のコードを書きテーマファイル直下に editor-style.css を置いてください。

functions.php
add_editor_style('editor-style.css');

bootstrap の内容をごっそりコピーしてあげれば、ビジュアルエディタの中身がごっそり bootstrap の CSS に置き換わります。

以上です。おつかれさまでした

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.