やりたいこと
- ユーザがアクセスしてくるデバイスに応じて、表示するviewを変えたい。
- viewファイルや静的ファイルはデバイス別にディレクトリを分けて管理したい(以下イメージ)。
views
│
├── pc
│ │
│ ├── sample
│ │ ├── index.html.erb
│ │ └── new.html.erb
│ │
│ └── layouts
│ └── application.html.erb
│
└── smartphone
│
├── sample
│ ├── index.html.erb
│ └── new.html.erb
│
└── layouts
└── application.html.erb
assets
│
├── images
│ │
│ ├── pc
│ │ └── foo.png
│ └── smartphone
│ └── bar.png
│
├── javascripts
│ │
│ ├── pc
│ │ └── application.js
│ └── smartphone
│ └── application.js
│
└── stylesheets
│
├── pc
│ └── application.css.scss
└── smartphone
└── application.css.scss
調べてみると
まず、「デバイス別にほげほげする」という文脈では、
jpmobileという国産gemが良さそうなことが分かりました。
jpmobile
https://github.com/jpmobile/jpmobile
参考
Rails 3.2 + jpmobile でスマートフォン対応したみた
http://blog.inouetakuya.info/entry/20120418/1334750857
今最もモテる組み合わせのRails3.1 + jp_mobile でサイトを作った際のメモ
http://a-newcomer.com/23
しかし
jpmobileの活用事例では、基本的にviewファイルの管理方法が
以下のようにファイル名自体にデバイス情報を含めて管理する形
でした。
views
│
│── sample
│ ├── index.html.erb
│ ├── index_smart_phone.html.erb
│ ├── new.html.erb
│ ├── new_smart_phone.html.erb
│ ├── show.html.erb
│ └── show_smart_phone.html.erb
│
└── layouts
├── application.html.erb
└── application_smart_phone.html.erb
これでも良いのですが、「PC版のみ(orスマートフォン版のみ)いろいろ調整したい」
というシーンが増えてくる(サービスの運用フェーズでは基本的にこれが多い)と、
views配下が徐々に雑然としていきそうでした。
ということで、「やりたいこと」で書いたようなpc/smartphone毎にディレクトリを
分離した構造にする方法を以下メモ。
デバイス毎に利用するviewファイルを切り替える
- jpmobileの機能でデバイス(pc/スマホ)を判別
- 判別に応じて、参照するviewsのパスを決定(ActionController::Base#prepend_view_path)
class ApplicationController < ActionController::Base
include Jpmobile::ViewSelector
before_filter :set_view_path
~
private
def set_view_path
path = request.smart_phone? ? 'smartphone' : 'pc'
prepend_view_path(Rails.root + 'app/views' + path)
end
end
viewファイルの振り分けはこれだけでok。
次に、読み込むassetsファイル(css/js/画像)の調整です。
css/jsの管理
各application.html.erbで、読み込みたいassetsのディレクトリを制御する
pc
<%= stylesheet_link_tag "pc/application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "pc/application", "data-turbolinks-track" => true %>
smartphone
<%= stylesheet_link_tag "smartphone/application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "smartphone/application", "data-turbolinks-track" => true %>
各application.css.scssで、インクルードするcssファイルを制御する
pc
/*
~
*= require_self
*= require_tree ../pc
*/
smartphone
/*
~
*= require_self
*= require_tree ../smartphone
*/
各application.jsで、インクルードするjsファイルを制御する
pc
~
//= require jquery
//= require jquery_ujs
//= require_tree ../pc
smartphone
~
//= require jquery
//= require jquery_ujs
//= require_tree ../smartphone
画像の管理
画像については、各viewファイルから、ディレクトリとファイル名を指定して呼び出してやるだけです。
(cssやjsと違い、application.css/jsといった親ファイルにインクルードする必要がないので。)
pc
<%= image_tag "pc/foo.png" %>
smartphone
<%= image_tag "smartphone/bar.png" %>
これで完成です。