1. miminashi

    No comment

    miminashi
Changes in body
Source | HTML | Preview
@@ -1,32 +1,70 @@
このへんをいじればいけそう。
```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** を見ればいいっぽい。
-まだ試したわけじゃないんでそのうち試す。
+<del>まだ試したわけじゃないんでそのうち試す。</del>
+試したし動いた。
+
+```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/gtt_core/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, GttCore::Patches::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をコピーして改変したものをプラグイン側にもたせておくのはあまりスマートでない気がする(コードを流用するとなるとRedmineのライセンスに従わないといけないとか; まあMITライセンスなのであんま問題にならないけど)んで、文字列で渡されるテンプレートのソースコードをコードから変更する案。
+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
こちらに関してもまだ一切何も試してない。