LoginSignup
5
9

More than 5 years have passed since last update.

Redmine APIの結果にプラグインからカラムを追加する

Last updated at Posted at 2014-05-13
  • 単に app/views/issues/*.api.rsb に対応する plugins/my_plugin/app/views/issues/*.api.rsb を置くだけでした
  • つまりhtmlを出力する.erbテンプレートと同じ手順でAPIの出力も改変できます
  • なんで気づかなかったんだろうこれ・・・orz
  • *.api.rsb だけ置き換えると ActionView::Template::Error が発生するので、*.html.erbも同時にコピーせよとのことです
このへんをいじればいけそう。 ```lib/redmine/views/api_template_handler.rb module Redmine module Views class ApiTemplateHandler def self.call(template) "Redmine::Views::Builders.for(params[:format], request, response) do |api|; #{template.source}; self.output_buffer = api.output; end" end end end end ``` **template.source** はテンプレート(app/views/issues/index.api.rsb など)のソースコードを返しているので、pluginからself.callを横取りすれば任意の別のテンプレートを差し込めるっぽい。 どのコントローラ/アクションのテンプレートを呼び出しているかは **template.virtual_path** を見ればいいっぽい。 まだ試したわけじゃないんでそのうち試す。 試したし動いた。 ```plugins/my_plugin/lib/my_plugin/patches/api_template_handler_patch.rb module ApiTemplateHandlerPatch module ClassMethods def hello puts 'Hello, from plugin' end def call(template) case template when 'app/views/issues/show.api.rsb' then template = 'plugins/my_plugin/app/views/issues/show.api.rsb' # 改変済みの.rsbファイル end p template super(template) end end def self.prepended(base) class << base prepend ClassMethods end end end ``` ```plugins/my_plugin/init.rb ActionDispatch::Callbacks.to_prepare do Redmine::Views::ApiTemplateHandler.send(:prepend, ApiTemplateHandlerPatch) end ``` Redmineのプラグインでは ``alias_method_chain`` を使ってメソッドの再定義を行っている例が多いけど、ruby2.0以降のみで動けばいいなら ``Module#prepend`` を使うと見通しがよくなる。 * [ruby - How to prepend classmethods - Stack Overflow](http://stackoverflow.com/questions/18683750/how-to-prepend-classmethods) * [Ruby2.0のModule#prependは如何にしてalias_method_chainを撲滅するのか!? TECHSCORE BLOG](http://www.techscore.com/blog/2013/01/22/ruby2-0%E3%81%AEmodule-prepend%E3%81%AF%E5%A6%82%E4%BD%95%E3%81%AB%E3%81%97%E3%81%A6alias_method_chain%E3%82%92%E6%92%B2%E6%BB%85%E3%81%99%E3%82%8B%E3%81%AE%E3%81%8B%EF%BC%81%EF%BC%9F/) ## template.sourceを直接いじるには? Redmineのプラグインテンプレートである.rsb(中身はただのrubyのDSLっぽい)をコピーして改変したものをプラグイン側にもたせておくのはあまりスマートでない気がする(コードを流用するとなるとRedmineのライセンスに従わないといけないとか; まあMITライセンスなのであんま問題にならないけど)んで、文字列で渡されるテンプレートのソースコードをコードから変更する案。 [Ripper](http://i.loveruby.net/w/RipperTutorial.html)でAST(抽象構文木)が取得できるので、template.sourceをASTに変換して、ASTをいじってソースコードに変換すればよさそう。 ASTからソースコードへの再変換は[sorcerer](https://github.com/jimweirich/sorcerer)が使えるっぽい。 * http://www.todesking.com/blog/2014-04-29-highlight-ruby-local-variables-in-vim/ * http://stackoverflow.com/questions/4878032/how-would-i-recompile-rippers-ast-back-to-ruby-code こちらに関してもまだ一切何も試してない。
5
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
9