2015.07.26 投稿
やることが多いのでコードベースで淡々とその方法を書きます。今回の要件は以下を想定
- TinyMCE ビジュアルエディタに「テキストボックスを吐き出す」ボタンを追加
- ボタンを押すとダイアログが開く
- ダイアログはこんな感じ
バージョン
- WordPress 4.2.3
functions.php の編集
TinyMCE にオリジナルのボタンを追加するにあたっては、(WordPressではなく)TinyMCE のプラグインを作成する必要があるようです。ちなみにプラグインは js で作ります。
プラグインを WordPress に対応させるにあたってまずは、add_filter 'mce_buttons' でボタンを追加。add_filter 'mce_external_plugins' でプラグインとなる js を登録することになります。
<?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 の編集をするよ
(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 addHidden()
{
$path = get_bloginfo( 'template_directory' );
echo '<input type="hidden" id="templateDirectory" value='."{$path}".' />';
}
add_action('admin_menu', 'addHidden');
これで js からのパスの心配はなくなります。
ダイアログ画面の作成
View はこんな感じで。
<!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;" /> <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 はこんな感じです。
(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() でカスタムダイアログを閉じます。
最後に
ビジュアルエディタには以下のアイコンを用意
こんな感じで表示されます
このアイコンは、editor_plugin.js の addButton() のパラメータでパスを指定してます。
ed.addButton(
'input_text',
{
title: 'input text',
image: path + '/inc/assets/images/input.png',
cmd: 'input_text_cmd'
}
);
実際にテキストボックスを追加してみます。まずはビジュアルエディタ側。
HTMLはこんな感じになります。
以上でカスタマイズの流れとなります。カスタムダイアログに関する情報が少なめだったので、TinyMCEの本家サイトでコードを漁りました。
慣れればカスタムのボタンをガンガン追加して、AddQuickTagなどのプラグインが無くてもよりインタラクティブなUIを提供できるようになります。
おまけ
ビジュアルエディタにオリジナルのCSSを適用させるには、functions.phpに以下のコードを書きテーマファイル直下に editor-style.css を置いてください。
add_editor_style('editor-style.css');
bootstrap の内容をごっそりコピーしてあげれば、ビジュアルエディタの中身がごっそり bootstrap の CSS に置き換わります。
以上です。おつかれさまでした