Rails4.1にgemでbootswatchを適応する

Webサイトのデザインにおいて,twitter bootstrapを使ったことがある人は多いと思う.

Railsに限った話ではなく,俺のようにデザインセンスが芽吹きもせずに育ってしまった人間であっても,ある程度まっとうな,キレイなサイトがつくれてしまう.


それはそれは素晴らしいので,RailsではGemで簡単に入れられたりします.

その辺はこういうサイトを参考にしてもらうとして…….


simple_formとTwitter bootstrapで作る俺流鉄板Railsアプリ(その1) | Oh My Enter!



今回は,bootstrapをベースとしているテンプレートであるところの,bootswatchを使ってみたくなった.


bootstrapは便利ではあるけれど,デフォルトのまま使うと,どれも同じデザインになってしまって面白味がない(使い方の問題が大きい).
確かにキレイなのだけれど,そのキレイな色すら使いこなせないので,もうちょっとガッツリテンプレートになっていると嬉しいんですね.

bootswatchってなに

これです.

Bootswatch: Free themes for Bootstrap



すでにテンプレートになっているので,bootstrapが入っているところに,これらのcssとjsを突っ込むだけ!
あとは好きなテンプレートを選んでおいてねっていう,実に素晴らしいサイトです.


Gemで入れたい

こういうの,かつてのRailsであれば,pluginsかvendorあたりに突っ込んでおけばよかったんですが,plugingsはRails4.0から廃止になりました.

出来る限りGemで入れようねっていうのがRailsの方針なのかなぁー…….

というわけでbootswatchのデザインテンプレートをGemで入れることを決意しました.

twitter-bootswatch-rails


まず検索して出てきたのは,このGemでした.

scottvrosenthal/twitter-bootswatch-rails · GitHub


紹介記事.

[Rails 4.x][Bootstrap] Rails 4.x で Bootswatch を使う方法 - Qiita



しかし,この通りにやってもエラーを吐かれます.

Less::ParseError - variable @zindex-modal-background is undefined
  (in "ApplicationPath"/app/assets/stylesheets/readable/loader.css.less):

仕方ないので,zindex-modal-backgroundを強制的に定義してやると……
表示はされました.

しかしいまいちbootswachのテンプレートデザインと差異があるぞ?

フォントとか,navbarのデザインが違う.


もしかして古いのかなぁー……ということで断念.

なにしろこのGem,Last commitが2014年6月28日なので,しばらく更新していない感が否めない.


rails-assetsからbootswatchをひく

Rails Assetsというサービスがありまして,こちらはRailsで使うassets関連のものたちを大量にストックしてくれていて,それらをGemで突っ込めるんですね.
bootswatchレベルで有名なものならあるだろうと思ったら,見事にありました.


Rails Assets


Component listからbootswatchを探すと,rails-assets-bootswatchとrails-assets-bootswatch-scssという2つがでてきました.どっちでもいいので,rails-assets-bootswatchを使います.


基本的なRails Assetsの使い方と同じですが,Gemfileに

source 'https://rails-assets.org'

gem 'rails-assets-bootswatch'

として,bundle installかけるだけです.


あとは,これらのファイルをapplication.cssで読み込みます.

/*
 *= require bootswatch/readable/variables
 *= require bootswatch/readable/bootstrap
 *= require bootswatch/readable/bootswatch
 *= require_self
*/


しかし!

Less::ParseError - variable @headings-font-family is undefined
(in "ApplicationPath"/vendor/bundle/ruby/2.1.0/gems/rails-assets-bootswatch-3.3.1.2/app/assets/stylesheets/bootswatch/readable/bootswatch.less):
  at "ApplicationPath"/vendor/bundle/ruby/2.1.0/gems/less-2.6.0/lib/less/js/lib/less/parser.js:604:in...

と怒られる……ここもか…….
font-familyを直打ちするのは,これ入れてる意味ないじゃん…….


[結論]bootswatch-railsを使う

maxim/bootswatch-rails · GitHub


だいたいこの通りにインストールすればいけます.

Gemfile

gem 'sass-rails', '~> 4.0.3'
gem 'bootstrap-sass'
gem 'bootswatch-rails'


application.cssはsassを使うように変更します.

application.css.scss

@import "bootswatch/readable/variables";
@import "bootstrap";
@import "bootswatch/readable/bootswatch";


sassを使う都合上,js側にも変更が必要です.

application.js

//= require jquery
//= require jquery_ujs
//= require bootstrap-sprockets
//= require turbolinks
//= require_tree .

これで見事にreadableのテンプレートデザインが適応されました.
長かった…….




precompileでこける

これ,実は本番環境でもちょっと問題がありまして,bootswatch内のscssファイルがassets:precompileでこけます.

以下のようなエラー.

Sass::SyntaxError: Undefined variable: "$navbar-default-bg".
  (in "ApplicationPath"/vendor/bundle/ruby/2.1.0/gems/bootswatch-rails-3.2.3/vendor/assets/stylesheets/bootswatch/amelia/_bootswatch.scss:16)

ameliaを使っているわけではないのですが,precompileでこけます.

理由は簡単で…….


config/initialize/assets.rb内で,

# Be sure to restart your server when you modify this file.

# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += %w( *.js *.css *.less *.erb )

っていうことをしているために,gemで読み込んでいるcssファイルもprecompile対象になっているからなんですね…….


対処療法的なのですが,precompileのリストからgemのassetsを外しましょう.

Rails.application.config.assets.precompile += %w( *.js application.css *.erb )

とするだけで通るようになります.

ちなみに実は,application.css自体はすでにprecompileのリストに含まれているので,これ書かなくてもいいですね.


そもそもこういう記述にしていたのは,layoutファイルを複数使って,cssファイルも複数使用していたために必要になっていたので…….
この辺りは個別に追加してやった方が安全なのかもしれません.



というわけで無事にbootswatchのデザインが適応できました.



※っていうかprecompileでameliaがコケるってことは,ameliaのデザイン適応したらまたエラー吐くんじゃないか…….