ActiveAdminで各ページ共通でレイアウトの構成要素をいじる


シチュエーション

ActiveAdminは特に何もしなくてもデフォルトのレイアウトが適用されてかなり見やすいページを作成できます。
ただ、たまに、そのレイアウトを一部変更したくなったりすることがあります。レイアウトのテンプレートファイルがどこかにあったりするわけではないので、普通には変更できません。

実装

例えば、全てのページのコンテンツの上にTwitterのボタンを置きたい場合。

lib/monkey_patches/active_admin/views/pages/base.rb
module ActiveAdmin
  module Views
    module Pages
      class Base
        def build_main_content_wrapper
          div id: "main_content_wrapper" do
            div id: "main_content" do
              para <<-'EOS'.html_safe
<a href="https://twitter.com/share" class="twitter-share-button">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
              EOS
              main_content
            end
          end
        end
      end
    end
  end
end

解説

ActiveAdminの描画処理は、箇所ごとに分かれた描画コンポーネントが行っているので、これにモンキーパッチを当てます。
prependなりでスマートにできると良いのですが、コンポーネントの構成によって出来ない場合があり、その場合はこの例のようにメソッドを上書きしたりもします。(上記の例は、元々の処理からの変更はparaの一文を追加しているだけです)
パッチを当てるべきコンポーネントとメソッドは、当てる前のページの、該当の要素のidで、ActiveAdminのソースコードをgrepすれば、だいたいすぐわかります。