Edited at

Railsでpublic以下の静的ページ(404.htmlといったエラーページ等)をデプロイ時に生成するgemを作った


はじめに: 404.htmlや500.htmlといったエラーページをhtmlで直接書くのって面倒じゃないですか?

Railsでは独自デザインの404ページや500ページをpublic/404.htmlpublic/500.htmlに置くことができます。

ただし、このファイルは静的なファイルなので、HTMLやCSSも静的にしなければなりません。

そのためデザインをサイト全体で合わせようとして、以下のようにHTML内にがんばって静的なCSSを埋め込んだりしているケースもあるのではないでしょうか?


public/404.html

<html>

<head>
<style type="text/css">
// コンパイル済みのapplication.cssからコピペした自前のCSSが何百行も並んだり
// ...
// ...
// ...
</style>
<!-- もしくはpublic以下に専用のcssファイルを用意したり -->
<link rel="stylesheet" media="all" href="/css/errors.css" />
</head>
<body>
<h1>404 Not found</h1>
<p>ページが見つかりません。</p>
</body>
</html>

この問題を解決するために、hanmotoというgemを作りました。

このgemは弊社ソニックガーデンの複数のプロジェクトで1年以上、本番利用されてきた実績があります。

今回の記事ではこのgemの概要と使い方を紹介します。


何が出来るの?


  • hamlやslimを使って静的ページが書ける

  • WebpackerやSprocketsで生成したcssをそのまま使える

  • Layoutファイルを使ってエラーページをDRYに管理できる

  • link_to等のヘルパーが使える

  • public以下にファイルが吐き出されるので、railsが死んでも表示出来る


インストール


Gemfile

gem 'hanmoto'


$ bundle install


使い方


404.htmlの例


レイアウトを用意


app/views/layouts/public.html.haml

!!!

%html
%head
%title #{yield(:title)} | MyAPP
= stylesheet_pack_tag 'application', media: 'all'
= favicon_link_tag '/favicon.ico'
%body
= yield


ビューを用意


app/views/public_pages/404.html.haml

- provide(:title, 'Not found')

%h1 Not found
%p This webpage is not found.
%p= link_to 'Home', root_path


public以下にファイルを生成

$ rake assets:precompile

OR

$ rake hanmoto:publish

.gitignorepublic/404.htmlを追加しておいて、デプロイ時にrake assets:precompileまたはrake hanmoto:publishを実行するという使い方を想定しています。


出力結果


public/404.html

<!DOCTYPE html>

<html>
<head>
<title>Not found | MyAPP</title>
<link rel="stylesheet" media="all" href="/packs/css/application-cc5b8b21.css" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
</head>
<body>
<h1>Not found</h1>
<p>This webpage is not found.</p>
<p><a href="/">Home</a></p>
</body>
</html>


htmlファイル以外の例


robots.txtを動的に生成する場合


app/views/public_pages/robots.text.erb

<% unless Rails.env.production? %>

User-Agent: *
Disallow: /
<% end %>


設定


config/initializers/hanmoto.rb

Hanmoto.configure do |config|

# ビューファイルを置くディレクトリを変更したい場合は指定してください
# config.view_dir = 'public_page'

# レイアウトファイルを変更したい場合はファイルタイプ別に指定してください
# config.layouts = {
# html: 'public',
# }
end



その他


仕組み


Herokuでも使える?

RailsアプリをHerokuにデプロイすると自動的にrake assets:precompileが実行されるので、特に意識する必要なく利用できます。


gemの名前の由来

publicに書き出す -> publisher -> 版元


リポジトリ

https://github.com/aki77/hanmoto