Lokkaにファイルアップロード機能を追加してみた
クラウド環境に対応したCMS/Blogツール、『Lokka』にファイルアップロード機能を追加してみました。
ソース
本家のソースにはマージされていませんので、私のGitHubからどうぞ。インストール方法などは、変わりません。HerokuやGAEは、ローカルストレージへの保存に対応していません。したがって、クラウド環境に完全に対応したバージョンではありませんのでご注意ください。
http://github.com/nkmrshn/lokka-uploaders *1
http://github.com/nkmrshn/lokka-db_uploader
http://github.com/nkmrshn/lokka-file_uploader
設定
デフォルトは、upload_filesテーブルのdataフィールド(TEXT型)に、バイナリファイルをBase64でエンコードしたものを保存します。
ローカルストレージに保存したい場合は、サイドメニュー[プラグイン]->[ファイル]をクリックし、アップロード先を[File]に変更してください。保存先のパス名を入力し、[編集]ボタンをクリックして変更を反映します。この設定は最初にやっておかないと、DBに保存されたバイナリファイルをローカルストレージに書き出す(またはその逆)ことはしませんので注意が必要です。
使い方
サイドメニューの[ファイル]->[登録]でファイルをアップロードしてください。
画像ファイルをアップロードした場合は、ページを登録する際のテキストエリアに表示されるツールバーから画像ファイルを挿入する(imgタグ)ことができます。
画像以外のファイルを挿入する(aタグ)際のURLは、サイドメニューの[ファイル]->[一覧]で表示される[ファイル名]で参照できます。
プラグインの構造
APP_ROOT/public/plugin/lokka-uploaderが基本となっていますが、ファイルの保存先によって処理が異なる部分は、別のプラグインがあります。DBに保存するプラグインは、APP_ROOT/public/plugin/lokka-db_uploader。また、APP_ROOT/public/plugin/lokka-file_uploaderは、ローカルストレージにファイルを保存します。
プラグイン名の「db」や「file」部分が重要で、どのプラグインを使うかはこの名前に依存しています。したがって、新しくPicasaに保存するプラグインを作る時は、「lokka-picasa_uploader」などとなります。
これは、APP_ROOT/public/plugin/lokka-uploader/uploader.rbのUploadFileクラスで、この名前を使っているからです。以下は、その抜粋ですがupload_type変数に名前が代入されます。
def upload(tempfile) __send__('upload_' + upload_type, tempfile) end
そして別のプラグインでは、これに対応したメソッドが必要になります。例えば、lokka-file_uploaderのfile_uploader.rbでは、ファイルをローカルストレージに保存しています。
def upload_file(tempfile) absolute_path = File.join(Option.upload_files, path) FileUtils.mkdir_p(absolute_path) unless File.exist? path size = tempfile.size read_size = size < READ_BUFFER ? size : READ_BUFFER while tmp = tempfile.read(read_size) File.open(File.join(absolute_path, name), "ab") { |f| f.write(tmp) } size = size - read_size read_size = size < READ_BUFFER ? size : READ_BUFFER break if read_size <= 0 end end
一方、lokka-db_uploaderでは次のようにupload_filesテーブルのdataフィールドに保存するようになっています。
def upload_db(tempfile) self.data = [tempfile.read].pack('m') self.save! end
これら保存先によって処理の切り替えるプラグインは、以下の5つが必ず実装されている必要があります。<名前>は、先ほど説明したプラグインの名前、「db」や「file」のことです。
- self.registered(app)メソッド内
- UploadFileクラス
- upload_<名前>(保存する時に呼ばれる)
- remove_<名前>(削除する時に呼ばれる)
- download_<名前>(外部からダウンロードされる時に呼ばれる)
この他、プラグイン固有の値を設定するビューに、inputタグのtype属性がhiddenでname属性が「redirect_to」がある場合、フォームをsubmitした後、value属性に指定したURLにリダイレクトします。
詳しくは、APP_ROOT/public/plugin/lokka-file_uploader/lib/file_uploader.rbなど直接ソースをご覧ください。何をやっているのか、大体の検討はつくかと思います。
問題点
プラグイン単体でソースを提供できなかったのは、Lokka本体のソースを修正しないと対応できない部分があったからです。管理画面のサイドメニューなど、主にビューまわりはプラグイン側で追加することができない為、直接ソースを変更しなければなりませんでした。i18nも、APP_ROOT/i18nに保存したen.ymlおよびja.ymlを修正する必要がありました。