pukiwiki改造/Edit改造その2
表記、友瀬のサイトで実施している独自拡張。
他の方にも役に立つと思われるので、一応公開しておきます。
この改造は「Editプラグインの振舞い」を変えるものです。
友瀬のサイトでは一般への編集は許可していませんが、さすがにこの場合動作がわからないと理解しづらいと思われるため、テストページを準備しました→テストページ
どんな感じか、触ってみてください。
改造目的†
Pukiwikiの編集画面において「Ajaxを用いてリアルタイムなプレビュー動作」を実現します。
これによって「疑似的WYSIWYG的な編集」を実現するものです。
編集中に適時Ajaxでサーバにリクエストを行い「pukiwikiマークをhtml化」しているので、Editプラグインによる通常の編集に比べるとサーバへの負荷が高まります(頻繁にプレビューをされているのとの似たようなもの)。
もしこれを採用しようとしている場合、お使いのサーバの負荷状態を考慮して採用してください。
改造の概要†
前提として、別途提示のプレビューの表示方法の変更の改造を行っています。
そのうえで Ajax動作させるために、次の改造をしています。
- lib/html.php の改造
- lib/html.php の edit_form() という関数で生成している編集用のテキストエリアを ajax 動作させるために、パラメータを編集します。名前の衝突に起因する編集・プレビュー動作の誤動作を避けるための変更です。
同じくedit_form()で生成している「プレビューボタン」を削除します。プレビューはajaxで適時実現するためです。Ver1.01でeditプラグイン側で実施するように変更しました。
- Editプラグインの改造
- ブラウザからの編集操作時に呼ばれる plugin_edit_action() の中で、ajax用のリクエストを受け取り・分岐する処理を追加。
加えて ajaxの応答用の新規関数を追加。 - 編集開始時のページ生成で、ajax用の javascript も戻すように変更。
- ajaxでプレビューを行うので、標準の「プレビューボタン」は非表示としています。
- ブラウザからの編集操作時に呼ばれる plugin_edit_action() の中で、ajax用のリクエストを受け取り・分岐する処理を追加。
具体的な改造内容†
結構変更が多いので、詳細割愛(笑)
おおざっぱには次の通りです。
- lib/html.php
- 編集用の textarea を次のように変更。
<textarea name="edit_msg" rows="$rows" cols="$cols">- 名前を変更しているので、Editプラグイン他、edit_form()を使う他のプラグインへの干渉も気を付けてください。
- 編集用の textarea を次のように変更。
- Editプラグイン内改造
- テキストエリアの名前変更に合わせた改造。
何か所かある $vars['msg'] を $vars['edit_msg'] に置き換え。 - plugin_edit_action() 内、最初のほう。次のようなAjaxリクエストの分岐処理追加。
} else if (isset($vars['ajax'])) { //tomose 追加処理 return plugin_edit_ajax($vars['cur_text']); }
- 新規 function plugin_edit_ajax($) の追加。
ブラウザからajaxでリアルタイムに呼び出される。
引数として渡された「編集中のpukiwikiマークダウンテキスト」を convert_html()して戻すが、その際に return ではなくecho & exit;するのがポイント。
returnすると「urlでのサイト全体(例えば左メニューバーなど)」を戻してしまうため。- 動作環境によって文字化けする恐れがある。おかしい場合この処理の中で実施している mb_convert_encoding() のエンコーディング方法を変更すること。
- ajax動作用の Javascriptをいろいろ追加。
- 編集エリアでの操作をプレビュー領域に反映するための、操作イベント監視のためのリスナー追加。
「編集」と「スクロール」に対応。 - 「編集」されたときの対応:2秒間新たな編集が発生しなかったときに、ajaxリクエストを実施する処理の追加。
そのajaxリクエストへの応答が戻ったら、プレビューエリアに反映する処理追加。 - 編集エリアが「スクロール」されたとき、プレビューエリアも同じ比率でのスクロールをする処理追加。
- 「プレビュー」ボタンを非表示に。
- 編集エリアでの操作をプレビュー領域に反映するための、操作イベント監視のためのリスナー追加。
- テキストエリアの名前変更に合わせた改造。
pukiwiki1.5.4 での実現例を添付しますので、詳しくはそちらを参照ください。(ファイル名に 「101」とあります:そのまま使う場合 edit.inc.php への変名が必要)
メモ。†
- 友瀬の場合、直接編集権限を他ユーザに渡していないので、ajax通信の細かいエラー処理とかはしていません。
一般向けにするとなると、例えば負荷集中したときに待たせるとか、何か考えないとならないかもしれません。 - これもサーバ側負荷問題で、ajaxのリクエストは「編集エリアで文字入力後、2秒間新たな変更が行われなかったとき」に行うようにしています。ただこれだと正直「鈍い」のも確かなので、利用者が正規ログインしている場合(編集者の名前が特定できているかどうか)1秒で更新するようにしています。
- Editプラグイン内で定義しています:
一般利用者向け時間は PLUGIN_EDIT_AJAX_TIMING、ログイン済利用者にはPLUGIN_EDIT_AJAX_TIMING_AUTHEDUSER。
- Editプラグイン内で定義しています:
- 改善の余地メモ。
現バージョンでは、lib/html.phpの edit_form() 周りをいろいろいじっている(イベントリスナー追加やプレビューボタンの削除)けど、これは editプラグイン側で対応するようにしたほうがいいかも。他のプラグインへの影響を抑える意図。Ver1.01で対応済。編集エリアとプレビューエリアの同時スクロールをサポートしたほうがいいかも。
ただ、入力エリアの行数とプレビューの行数は変わる(プラグイン処理した結果増減する)ので、それをどう吸収するか。
Ver1.01で対応済。編集領域とプレビュー領域の行数比率でスクロール。Pukiwikiの仕様上、一部のプラグインのように「編集マークダウンでのテキスト行数」と「実際の表示行数との間でギャップが大きい(例えば編集上何行になっていても折りたたみの divregionを使うと1行になるなど)場合妥当な位置にならないので、その場合は「入力エリアに合わせてスクロール」のチェックボックスを外して手動操作してください。
コメント†
ご意見などがあれば。