プロジェクト

全般

プロフィール

Tips wiki » 履歴 » バージョン 3

Mitsuyoshi Yoshida, 2011/07/07 03:00

1 1 Mitsuyoshi Yoshida
h1. wiki 編集機能の追加
2
3
{{>toc}}
4
5
プラグインに wiki 編集機能を付ける方法の Tips です。
6
[[プラグイン開発ガイド]] では簡単な wiki 編集機能は付けました。ここでは他の wiki のように以下の機能も追加します。
7
8
* プレビュー
9
* 添付ファイル
10
11
wiki 編集機能だけの場合の説明はプラグイン開発ガイドを見てください。
12
13
* [[GuideNewAction#フォーム内のパラメータ|フォーム]]
14
* [[GuideActionElse#詳細表示-show-アクション-|表示]]
15
16
h2. サンプルコード
17
18
* "表示":http://code.google.com/p/myoshida-rp/source/browse/#svn%2Ftrunk%2FTips%2Falias%2Fwiki
19
* "ダウンロード":http://code.google.com/p/myoshida-rp/downloads/detail?name=sample-wiki.zip
20
21
サンプルはプラグイン開発ガイドのコードを改造したものです。
22
23
*フォーム*
24
25
!wiki_form.png!
26
27
*表示*
28
29
!wiki_show.png!
30
31
32
33
h2. プレビュー
34
35
プレビューでは新しくページを開くことなく、ページの内容を変更する必要があります。こういう処理には JavaScript が必要になります。しかし、 Rails ではこれを簡単に行える *link_to_remote* という関数が用意されてます。 Rails では *_remote* と付くのは JavaScript 実行用のもので、 link_to_remote では JavaScript を実行するリンクが作成できます。
36
37
:update オプションを使った link_to_remote では、リンクをクリックするとアクションを実行し、その結果をページの指定した場所に挿入します。
38
39
h3. 表示
40
41
プレビュー用のリンクを新規作成(new.html.erb)と編集(edit.html.erb)のフォーム送信ボタンの横に付けます。 wiki 編集機能を改良した new.html.erb は次のようになります。 edit.html.erb もほぼ同じように修正します。 
42
43
<pre><code class="rhtml">
44
<h2><%=l(:label_foos_new)%></h2>
45
46
<% labelled_tabular_form_for :foo, @foo,
47
                             {:html => {:multipart => true, :id => 'foo-form'}} do |f| %>
48
    <%= render :partial => 'foos/form', :locals => {:form => f} %>
49
    <%= f.submit l(:button_create) %>
50
    <%= link_to_remote l(:label_preview), 
51
                       { :url => {:action => 'preview', :id => @project },
52
                         :method => 'post',
53
                         :update => 'preview',
54
                         :with => "Form.serialize('foo-form')",
55
                         :complete => "Element.scrollTo('preview')"
56
                       }, :accesskey => accesskey(:preview) %>
57
<% end %>
58
<div id="preview" class="wiki"></div>
59
</code></pre>
60
61
変更点は 3 つです。
62
63
* フォームタグに ID を要素を付ける。
64
** {:html => {:multipart => true, :id => 'foo-form'}}
65
* link_to_remote でプレビュー用のリンクを付ける
66
* プレビューの表示場所を付ける
67
** <notextile><div id="preview" class="wiki"></div></notextile>
68
69
multipart も追加していますが、これは次で説明する添付ファイル用のものです。
70
71
link_to_remote は引数は以下のものを渡します。
72
73
# 表示名
74
# オプション
75
# html オプション
76
77
表示名には Redmine で定義されたプレビューのラベルを使い、 html オプションとしてプレビュー用のアクセスキーを設定しています。アクセスキーを付けるとどう変わるのかはよく分かりませんが、 Redmine のチケット、ニュース等は付いているの一応付けています。
78
79
link_to_remote の主な指定はオプションで行います。
80
81
|_. オプション |_. 説明 |
82
| :url      | アクションを指定するための url です。 preview アクションは今回新たに追加します。 |
83
| :method   | get または post を指定します。文字数が 256 を超える可能性があるので post を指定しています。 |
84
| :update   | 結果の挿入先の html 要素の ID を指定します。 |
85
| :with     | リンクと一緒に実行する JavaScript を記述します。リンクを実行したときにフォームの内容を params 変数に格納するための処理を行っています。 フォームに ID を追加したのはここで使用するためです。 |
86
| :complete | アクション実行後の JavaScript の処理を指定します。処理が完了したら、スクロールしてプレビューの内容が表示されるようにしています。 |
87
88
89
h3. コントローラ
90
91
コントローラ( foos_controller.rb )に link_to_remote から呼ばれる preview を追加します。
92
93
<pre><code class="ruby">
94
  def preview
95
    @text = params[:foo][:description]
96
    render :partial => 'common/preview'
97
  end
98
</code></pre>
99
100 2 Mitsuyoshi Yoshida
2 行目でフォームの説明(description)フィールドの内容を *@text* に入れ、3 行目で挿入する部分描画を行っています。 *code/preview* は Redmine で用意されているビュー用のテンプレートファイルで以下のような内容です。
101 1 Mitsuyoshi Yoshida
102
<pre><code class="rhtml">
103
<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
104
<%= textilizable @text, :attachments => @attachements, :object => @previewed %>
105
</fieldset>
106
</code></pre>
107
108
(@attachements のつづりが間違っている気がしますが、 1.2.0 ではこうなってました)
109
110
111
h3. preview アクションの権限
112
113
アクションを追加した場合には忘れずに init.rb で権限を指定していないとエラーになってしまいます。
114
115
<pre><code class="ruby">
116
  project_module :standard do
117
    permission :view_foos, :foos => [:index, :show, :preview]
118
    permission :manage_foos, {:foos => [:new, :edit, :destroy]},
119
               :require => :member
120
  end
121
</code></pre>
122
123
124
125
h2. 添付ファイル
126
127
添付ファイルを使えるようにするにはいろいろやることがあります。
128
129
* モデル
130
** 添付ファイルを使えるように指定
131
** プロジェクトメソッドの追加
132
* ビュー
133
** フォーム
134
*** マルチパートにする
135
*** 添付ファイル用のフィールドを追加
136
** 表示
137
*** wiki 解析で添付ファイルを使うように指定
138
*** 添付ファイルの表示
139
* コントロール
140
** attachments ヘルパーのインクルード
141
** 添付ファイルの保存
142
143
h3. モデル
144
145
<pre><code class="ruby">
146
class Foo < ActiveRecord::Base
147
  unloadable
148
149
  belongs_to :project
150
151
  acts_as_attachable :delete_permission => :manage_foos
152
153
  # :
154
155
  def project
156
    Project.find(:first, :conditions => "projects.id = #{project_id}")
157
  end
158
  
159
end
160
</code></pre>
161
162
*acts_as_attachable* メソッドを書くことにより、 foo クラスで添付ファイルが使えるようになります。 acts_as_attachable は Redmine が使用している Rails のプラグインで他のプラグインと同様に vendor/plugins 以下にデフォルトで置かれているものです。
163
引数はオプションで、ここでは添付ファイルを削除するのにサンプルデータの管理権限が必要なようにしています。
164
165
添付ファイルを使用する場合、 プロジェクトのオブジェクトを返すプロジェクトメソッドが必要となります。なぜ、必要なのかは実は私もよく分かりません。分かりませんが作っておかないと正常に動作しないのでとりあえず付けておきましょう。
166
167
*belongs_to* はモデルクラスの関係を記述しています。ここでの記述で foo は project に属していることになります。
168
project メソッドは自分の *project_id* メンバを使って、 [[GuideForProject#project-の設定|コントローラの時と同じ]] ようにプロジェクトオブジェクトを取得しています。
169
170
171
h3. ビュー
172
173
h4. フォーム
174
175 3 Mitsuyoshi Yoshida
まず、 プレビューで書いたコードのようにしてフォームはマルチパート(multipart)にしておく必要があります。これは http の決まりのようなものです。
176 1 Mitsuyoshi Yoshida
177
また、新規作成と編集で共通して使うフォーム( _form.html.erb ) に以下の行を追加します。ここも Redmine で使われているものをそのまま部分描画として使用します。
178
179
<pre><code class="rhtml">
180
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
181
</code></pre>
182
183
184
h4. 表示
185
186
wiki 解析結果の表示も少し変更する必要があります。
187
188
<pre><code class="rhtml">
189
<% unless @foo.description.blank? %>
190
  <p><strong><%=l(:field_description)%></strong></p>
191
  <div class="wiki">
192
    <%= textilizable @foo.description, :attachments => @foo.attachments %>
193
  </div>
194
<% end %>
195
196
<% if @foo.attachments.any? %>
197
    <hr />
198
    <%= link_to_attachments @foo %>
199
<% end %>
200
</code></pre>
201
202
wiki 解析時に添付ファイルも考慮するように *textilizable* のオプションで添付ファイルを渡しています。
203
また、 *link_to_attachments* で添付ファイルの情報とリンクを説明の下に追加しています。
204
205
206
h3. コントロール
207
208
添付ファイルを扱うメソッドは Attachments ヘルパーで定義されています。これを使うためにモジュールを include する必要があります。
209
210
<pre><code class="ruby">
211
  helper :attachments
212
</code></pre>
213
214
データの保存が終わった後、添付ファイルも保存する必要があります。 @foo.save が成功した後に以下の行を new, edit それぞれのメソッドで追加します。
215
216
<pre><code class="ruby">
217
        Attachment.attach_files(@foo, params[:attachments])
218
        render_attachment_warning_if_needed(@foo)
219
</code></pre>
220
221
1 行目が添付ファイルを保存する処理で、 2 行目がそのエラー処理を行っています。
222
223
---