その他
    ホーム 技術発信 DoRuby RailsのViewを自在にカスタマイズするための「Cosme」gem

    RailsのViewを自在にカスタマイズするための「Cosme」gem

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    既存のViewに手を加えずカスタマイズするためのRails向けgem「Cosme」を紹介します。

     はじめに

    Railsには便利なgemがたくさんあり、この中にはロジックだけでなく画面のデザインであるViewを含んだものが数多くあります(たとえばActiveAdminやDevise、Comableなど)。これらをこのまま利用できれば楽ですが、認証のための項目を増やしたいとか商品価格の横には定価を載せたいとか、やりたいことが増えてくるとその一部に手を加えたくなるケースが少なからずあります。

    通常Viewは一部分だけを変更することが不可能で、カスタマイズを行う場合はファイルを丸ごと置き換える形で対応することになります。ただしこの手法には、gemのバージョンアップの際にViewの更新を追うことができなくなってしまう、という欠点があります。

    今回はこの欠点を補いつつ既存のViewをカスタマイズするためのgem「Cosme」を紹介します。

     使い方

    1. gemのインストール

    bundlerを利用している場合は下記の行を Gemfile に追加します。

    gem 'cosme'
    

    2. JavaScriptライブラリの読み込み

    ※ v0.4.0 からこの操作は不要になりました。

    `app/assets/javascripts/application.js` に下記の行を追加します。

    //= require cosme
    

    3. ヘルパメソッドの組み込み

    ※ v0.2.0 からこの操作は不要になりました。

    `app/views/layouts/application.html.erb` の <body> タグ直下に下記の行を追加します。

    <%= cosmeticize %>
    

    4. カスタマイズ内容を定義

    カスタマイズ用のViewとメタ情報を記載した設定ファイルを `app/cosmetics` ディレクトリに設置します。

    カスタマイズの定義を行うために `Cosme.define` というメソッドを呼び出します。

    「target」はカスタマイズ対象で、jQueryのHTMLセレクタと同じ役割を果たします。

    「action」はカスタマイズ方法で、「before」「after」「replace」をいずれかを指定します。

    # app/cosmetics/after_example.rb
    Cosme.define(
      target: '.example',
      action: :after
    )
    
    <%# app/cosmetics/after_example.html.erb %>
    <h2>After Example</h2>
    

     結果

    これで、すべての `example` というCSSクラスを持つHTML要素の後に「After Example」と表示されるようになりました。

    例えば `app/views/layouts/application.html.erb` が下記のように `example` クラスを持つ要素を含んでいたとすると、最終的には「Example」のあとに「After Example」が表示されるようになります。

    <%# app/views/layouts/application.html.erb %>
    <html>
      <head>
        <title>Example</title>
        <%= stylesheet_link_tag '/application'/, media: '/all'/ %>
        <%= javascript_include_tag '/application'/%>
      </head>
      <body>
        <div class="example">
          <h1>Example</h1>
        </div>
      </body>
    </html>
    

    上記の結果、<body> タグ内は下記のようになります。

    <div class="example">
      <h1>Example</h1>
    </div>
    <h2>After Example</h2>
    

     しくみ

    CosmeはHTMLの置換処理を JavaScript 上で行っています。そのため動作速度や非JavaScript環境での動作を求める方にはあまりオススメできません。その一方でとてもシンプルな実装になっているためすべてのテンプレートエンジンに柔軟に対応できます。

    同じことを実現できる「deface」というgemがありますが、こちらはActionViewを拡張することで実装されているため対応テンプレートエンジンが限定されており、またその一部にバグがある*1状態です(*1 2015/10/1現在: slimにおいてブロック内の要素がHTMLエスケープされてしまう https://github.com/spree/deface/issues/133 )。ただし、動作速度を求めていてバグにも引っかからない場合はこちらのgemをオススメします。

     おわりに

    今回はViewのカスタマイズに便利なCosmeというgemを紹介しました。

    追加機能の要望や不具合の報告は こちら にリクエストすると中の人が対応してくれるかもしれません。

     関連リンク

    Cosme :: https://github.com/appirits/cosme

    Deface :: https://github.com/spree/deface

     改訂

    • 2015/10/18 :: v0.4.0へのバージョンアップに伴い、スクリプトの組み込みが不要になりました。
    • 2015/10/09 :: v0.2.0へのバージョンアップに伴い、ヘルパメソッドの組み込みが不要になりました。