プロジェクト

全般

プロフィール

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

Mitsuyoshi Yoshida, 2011/07/07 02:40

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