Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

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

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 に置き換わります。

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
20
Help us understand the problem. What are the problem?