LocomotiveCMS + Devise を使って作ったログインページのデザインをCMS側でできるようにする(1)


Devise が出力するビューを、LocomotiveCMS 側でデザインしたい!

先日、LocomotiveCMS にユーザー認証機能を組み込みましたが、デザインがこんな感じでした。

これではイケてないので、せっかくなので LocomotiveCMS 側のテンプレートをレンダリングできるようにしました。

まず、devise のコントローラーを拡張してみます。devise はデフォルトだと controller などのファイルは作成されませんが、自分で作ることもできます。

拡張用のコントローラーを作る

まずはユーザー登録からいきます。前回はusers モデルに対して認証機能を実装したので、app/controllers/users/registrations_controller.rb を作ります。

app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  def new
    logger.debug 'test'
    super
  end
  def create
    super
  end
end

routes.rb を以下のように変更します。

config/routes.rb
  devise_for :users, :controllers => {
    :registrations => 'users/registrations'                                                                                                                   
  }

この状態で、localhost/users/sign_up を表示すると、ログファイルに 'test' の文字が表示されます。

Liquid テンプレートを読み込む

では、今度は LocomotiveCMS のテンプレートを読めるようにしましょう。engine 側の /app/controllers/locomotive/public/pages_controller.rb を見てみると、Locomotive::Render と LocaleHelpers がなにやら関係してそうです。controller からインクルードしましょう。

  include Locomotive::Routing::SiteDispatcher
  include Locomotive::Render
  include Locomotive::ActionController::LocaleHelpers

device の大元のソースコードと、LocomotiveCMSのソースコードをマージさせたのが以下のソースです。
これで、テンプレートデザインにLocomotive側のCMSを利用することができるようになります。

app/controllers/users/registration_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
  include Locomotive::Routing::SiteDispatcher
  include Locomotive::Render
  include Locomotive::ActionController::LocaleHelpers
  before_filter :require_site
  def new
    build_resource({})
    @page ||= self.locomotive_page('/userregistration')
    respond_to do |format|
      format.html {
         render :inline => @page.render(self.locomotive_context({ 'user' => resource}))
      }
    end
  end
  def create
    super
  end
end

@page ||= self.locomotive_page('/userregistration')という部分で、/userregistration というテンプレートを読み込みに行っていますので、LocomotiveCMS の管理画面側でその名前を持ったテンプレートを作っておく必要があります。内容は以下のようにしました。このテンプレートがそのままサイトに表示される必要はありませんので、listed は false にしています。

/app/views/pages/userregistration.liquid.haml
---
title: ユーザー登録
slug: userregistration
listed: false
published: true
cache_strategy: none
response_type: text/html
---   
{% extends 'parent' %}
{% block main %}
.row
  .large-8.columns
    %h1 ユーザー登録ページ
    %form#new_user.new_user{"accept-charset" => "UTF-8", action: "/users", method: "post"}
      .hidden
        {% csrf_param %}
        %input{name: "utf8", type: "hidden", value: "✓"}/
      %div
        %label{for: "user_email"} Email
        %br/
        %input#user_email{autofocus: "autofocus", keyev: "true", mouseev: "true", name: "user[email]", size: "30", type: "email", value: ""}/
      %div
        %label{for: "user_password"} Password
        %br/
        %input#user_password{keyev: "true", mouseev: "true", name: "user[password]", size: "30", type: "password"}/
      %div
        %label{for: "user_password_confirmation"} Password confirmation
        %br/
        %input#user_password_confirmation{keyev: "true", mouseev: "true", name: "user[password_confirmation]", size: "30", type: "password"}/
      %div
        %input{name: "commit", type: "submit", value: "Sign up"}/
{% endblock %}

とりあえず既存のdevise で出力されたHTMLをHAMLに変換しただけです。devise 側のviewテンプレートではform_forなどを使っているのですが、残念ながら LocomotiveCMS の Liquid テンプレートでは form_for は使えません。また、注意点として、テンプレート内に{% csrf_param %}という文字が入っています。これは、FORMのパラメータにCSRF対策用の <input type="hidden" name="authenticity_token" value="DQoZGjuFVeiqetim……">というタグを埋めこむものです。

上記では parent を拡張しているので、http://yourhost/users/sign_up を表示すればサイト全体のデザインが適用されているはずです。

これで、Devise 側のページもCMSから編集することができるようになりました。

次の記事では、create メソッド側も修正します。
LocomotiveCMS + Devise を使って作ったログインページのデザインをCMS側でできるようにする(2)


Locomotive 関連の記事一覧:
* Locomotive Engine を Heroku で動かすまで
* LocomotiveCMS でニュース記事一覧機能を作る
* LocomotiveCMS のページにユーザー認証機能を組み込む(Engineの拡張)
* LocomotiveCMS + Devise を使って作ったログインページのデザインをCMS側でできるようにする(1)
* LocomotiveCMS + Devise を使って作ったログインページのデザインをCMS側でできるようにする(2)
* LocomotiveCMS + Devise を使って作ったログインページのデザインをCMS側でできるようにする(3)
* LocomotiveCMS で、複数の Heroku インスタンスを使う