コンテンツに飛ぶ | ナビゲーションに飛ぶ

パーソナルツール
現在位置: ホーム / Blog

ExSoft Blog

デベロッパーブログです。

Plone4のHTMLエディタ(TinyMCE)のツールバーに独自のボタンを追加する

最終変更 2012年07月02日 19時57分

動機

Plone4にはWYSIWYGエディタとしてTinyMCEが採用されています。

HTMLを知らないユーザーにとってページを編集する唯一のツールなので、このエディタの使い勝手はとても重要です。

デフォルトでも十分便利なエディタですが、サイトによってはお決まりのHTMLコードをツールバーのボタンを押すだけで挿入できたら便利な場面もあると思います。

そこで今回はPlone4でTinyMCEのツールバーに独自のボタンを追加するミニマムな方法を紹介したいと思います。

完成イメージ

先ずは完成イメージです。

ページ編集画面を表示すると以下のように独自のボタンが追加されます。

ボタンを押すと、カーソル位置に「ExSoft Test」という文字が挿入されます。

手順

先ず、TinyMCEのpluginコード(javascript)を記述します。

javascriptの配置方法はどんな方法でも良いですが、今回は最も前提が少なくて済むportal_skins/customにjavascriptコードをuploadする方法でいきます。

ファイル名はtinymce-testplugin.jsとします。(名前は任意です)

$(function(){

    var cmd_name = 'exsofttest';
    var btn_name = 'btn_exsoft_test';
    var plugin_name = 'plugin_exsoft_test'

    tinymce.create('tinymce.plugins.ExsoftTestPlugin', {

        init : function (ed, url) {

            var t = this;
            t.url = url;
            t.editor = ed;
            t.docs = false;

            ed.addButton(btn_name, {
                title : 'Exsoft Test',
                cmd : cmd_name
                /* image : url + '/exsofttest.gif' */
            });

            ed.addCommand(cmd_name, function (val, page) {
                var html = 'ExSoft Test';
                ed.execCommand('mceInsertContent', false, html);
            });

        }
                 
   });

   tinymce.PluginManager.add(plugin_name, tinymce.plugins.ExsoftTestPlugin);

});

addCommandに渡しているfunctionの実装だけが肝で、それ以外のコードは毎回お決まりです。

今回はこのfunctionの実装も「ExSoft Test」というplainな文字列を挿入するだけのミニマムなものとしています。

追加するボタンに使用するアイコンを指定する場合は、addButtonメソッドでURLを指定します。 今回は、既存ボタンのアイコン画像を使用する事にします。

既存ボタンのアイコンは、1つのgifファイル(*1)をbackground-positionで位置を調整する事で各ボタンのアイコンとしているので、 同じ方法でニコニコマークを独自ボタンに割り当てるためにploneCustom.cssに以下を記述します。

*1:アイコンgifは右参照 > [site-root]/portal_javascripts/Sunburst%20Theme/themes/advanced/img/icons.gif

.ploneSkin span.mce_btn_exsoft_test{
    background-position: -60px;
}

ここで指定するspanのclass名はpluginコードのbtn_nameと一致させる必要があります。(mce_のprefixは固定で付与する)

あとはPlone UIから[サイト設定] > [TinyMCEビジュアルエディタ]でTinyMCE設定画面を表示し各項目を設定します。

最初にカスタムプラグインを認識させる為に、[リソースタイプ]タブの[カスタムプラグイン]に以下を記述します。

plugin_exsoft_test|/tinymce-testplugin.js

|の左の値はpluginコード内のplugin_nameで指定した文字と一致させる必要があります。

|の右の値はpluginコードが参照できるURLと一致させる必要があります。

最後にツールバーにボタンを追加する為に、[ツールバー]タブの[カスタムツールバーボタン]に以下を記述します。

btn_exsoft_test

この値はpluginコード内のbtn_nameで指定した文字と一致させる必要があります。

お疲れさまでした。

以上で完成です。ページ編集画面のツールバーに独自のボタンが追加されている事が確認できると思います。クリックするとカーソル位置に文字が挿入されます。

あとはpluginコードを皆さんの要件にあわせるだけです。

TinyMCEのpluginコードについては本家サイトや eggs/Products.TinyMCE-x.x.x-py2.x.egg/Products/TinyMCE/skins/tinymce/plugins/table/js/table.js が参考になると思います。

技術者が自分の好きな技術を使うという事

最終変更 2012年05月30日 07時15分
最近ある機会に「どうしてこの技術を選択したのですか?」と聞かれる事がありました。その際ボクは「この技術が大好きだからです。」と答えたのですが、それをきっかけに、この答えの背景についてこんな事を考えたのでここにメモとして残します。

(ここで言う「使う」とはエンドユーザーとしての「使う」ではなくて、エンドユーザーに価値を提供する為に技術者が技術を「使う」を指しています。)

技術と技術者はセット

技術というものは本来、単独にはなり得なくて、必ずそれを使う技術者がいるものです。技術はそれを使う技術者とセットになって初めて成果を出します。

ということは当然、技術が発揮する成果量は技術者単体のパワーとかその技術者がどれだけその技術を使いこなせるか、応用できるかという要素がとても重要になります。

技術への情熱

成果量の一旦を担う技術者のパワーは、主観的な要素によって激変します。つまり技術者がその技術を好きか嫌いか、情熱を持てるか否かが成果量にとても大きく影響するのです。

技術単体だけでみると、解決対象となる問題に対して得手不得手があるのは当然ですが、それを誰が使うかが成果量を左右する重要な要素だとすると、その技術者との組み合わせで技術の選択をするべきなのだとボクは考えています。

つまり技術者が決まっている(例えば自分がやる事が前提)のであれば、その人が好きな技術、使いたい技術は「好きで情熱を持てる」その時点で他の技術よりも大きなアドバンテージがあるという事なのです。

一般的な企業が背負う重荷

企業活動においては、その人ありきはNGとされているので このような選択は中々できないとは思いますが、ある人がいなくなる事を前提にするという事は、ユーザーに価値を提供すると同時に、平凡な技術者が成果を出せる為の仕組みをつくらなければならないという重荷を負う事になります。変化が激しい技術業界において、これは重大すぎる重荷です。

最近ある機会に「どうしてこの技術を選択したのですか?」と聞かれる事がありました。その際ボクは「この技術が大好きだからです。」と答えたのですが、それをきっかけに、この答えの背景についてこんな事を考えたのでここにメモとして残します。

Plone4.1でのサイト設定画面の各項目と権限の対応

最終変更 2012年01月12日 03時10分

サイト管理者(Site Administrator)

皆さんのPloneサイトではユーザー管理を「管理者(Manager)」が行っていませんか?

Plone4.0まではサイト設定画面は管理者にしか表示されなかった為、ユーザー管理についても管理者が担当している事が多いと思いますが、この運用には問題があります。

例えば、ZMI内での作業やアドオンインストール、エラーログの確認については技術者グループに担当をお願いしたいですが、ユーザーの追加や権限付与については、技術者よりも人事により近い立場のグループに担当をお願いした方が効率がよいはずです。 だからといって、人事担当の方を管理者グループに所属させると、ZMIに入れてしまったりアドオンのインストールができてしまうので、それは避けたい事が多いはずです。

問題の根本は、Ploneの「サイト設定」画面に表示されている各設定項目は、運用上複数の担当者グループに分ける事ができますが、「管理者」という一つのロールしか存在しない点にあります。

この問題を解消する為に、Plone4.1からは初期状態で「サイト管理者(SiteAdministrator)」ロールが追加されています。このロールは、ZMI内での作業やアドオンインストールはできませんが、ユーザー管理やカレンダー設定が行えるようになっています。

管理者でログインした場合のサイト設定画面は以下です。(今まで通り全項目が使用可能)

setting4manager.png

サイト管理者でログインした場合のサイト設定画面は以下です。(使用可能な項目が制限されている)

setting4siteadmin.png

特に規模が大きめなサイト運営において、効率良い仕事の分散が出来るので、このロールの活用をおススメします。

権限の調整

初期状態でサイト管理者ロールに付与されている権限で概ね問題ないとは思いますが、組織によっては、ユーザー管理を担当する人事の方が「HTMLフィルタ設定」を変更できてしまう事を避けたい場合もあると思います。

Plone4.1ではサイト設定の各項目に対応する権限が個別に(全てではありませんが)定義されているので ZMIのPloneサイトルート[Security]タブでPermissionの設定をする事で組織にあわせた細かい権限の調整が可能になっています。

Ploneのサイト設定の項目とZMIのPermissionの対応についての調査結果は以下です。

Ploneサイト設定項目名ZMI[Security]タブのPermission
Discussion Manage portal
HTML Filtering Plone Site Setup: Filtering
TinyMCE Visual Editor Plone Site Setup: TinyMCE
Zope Management InterfaceManage portal
Configuration Registry Manage portal
Add-ons Manage portal
Errors Manage portal
Calendar Plone Site Setup: Calendar
Collections Manage portal
Content Rules Content rules: Manage rules
Site Plone Site Setup: Site
Security Plone Site Setup: Security
Types Plone Site Setup: Types
Themes Plone Site Setup: Themes
Navigation Plone Site Setup: Navigation
Markup Plone Site Setup: Markup
Maintenance Manage portal
Mail Plone Site Setup: Mail
Users and Groups Plone Site Setup: Users and Groups
Personal Preferences Set own properties
Search Plone Site Setup: Search
Image Handling Plone Site Setup: Imaging
Editing Plone Site Setup: Editing
Language Plone Site Setup: Language

例えば、サイト管理者にHTMLフィルタ設定を許可しないようにする為には、ZMIにてSite Administratorの[Plone Site Setup: Filtering]権限をOFFにします。

調査の仕方

サイト設定項目の権限についての調査結果は上記のとおりですが、Ploneの他の部分についても疑問に思った際にネット上に情報が無く、自身で調査が必要になる事もあると思います。

今回私が行った調査の流れについて書いておきますので、自身で調査が必要になった際に参考にしていただければと思います。

1) Ploneサイト設定ページのURLからview名が判明する(@@の後ろがview名)

overview-controlpanel

2) view名はzcmlファイルで定義されているので該当zcmlファイルを探す

find [plone-root]/eggs/ -name "*.zcml" | xargs grep overview-controlpanel

以下発見

plone.app.controlpanel-2.1.1-py2.6.egg/plone/app/controlpanel/configure.zcml

3) zcmlファイルを見るとclass名が判明する

<browser:page
	 name="overview-controlpanel"
	 for="Products.CMFPlone.interfaces.IPloneSiteRoot"
	 class=".overview.OverviewControlPanel"
	 permission="plone.app.controlpanel.Overview"
	 />

4) classのソース(plone/app/controlpanel/overview.pyのclass OverviewControlPanel)を見る

__call__メソッドの戻り値がhtmlとして描画されるので、メソッドの実装を見てみるとoverview.ptを返している事がわかる。

template = ViewPageTemplateFile('overview.pt')
...
def __call__(self):
   self.request.set('disable_border', 1)
   return self.template()

5) plone/app/controlpanel/overview.ptを見る

<tal:category tal:repeat="category view/categories">
	
	<h2 tal:content="category/title"
		i18n:translate="">Category</h2>

	<div tal:define="sublists python:view.sublists(category.get('id'))">

		<div tal:repeat="sublist sublists"
			 tal:condition="sublists"
			 style="float:left; margin-right: 1em; width: 29%">

			<ul class="configlets"
				tal:condition="sublist">
				<li tal:repeat="action sublist">

sublistが各設定項目を表現していて、sublistはview.sublistsから取得している事が判明する。

6) viewはOverviewControlPanelのインスタンスなので、再度plone/app/controlpanel/overview.pyのclass OverviewControlPanelを見る。

sublistsメソッドを調べる

def sublists(self, category):
    actions = self.cptool().enumConfiglets(group=category)
    return three_column_list(actions)
    
def cptool(self):
    return getToolByName(aq_inner(self.context), 'portal_controlpanel')

toolのportal_controlpanelを使用していることがわかる

7) toolはZMIで参照が可能なのでZMIでportal_controlpanelを見る。

各項目(Name,Idより判別)のPermissionを見ると必要な権限がわかる。

portal_controlpanel.png

Use the Source, Luke !

上記の調査を実際に行ってみると、結果だけではなく仕組みについても理解が深まったので、コントロールパネルに自身のviewを追加したり、より細かい権限設定を行う事も可能になりました。

「ソースを使え、ルーク!」という事で、やはりソースを追うと色々な可能性が見えてきまので、是非皆さんもソースを調べてみてください。