Memento memo.

Today I Learned.

PhoenixのTemplate Engineを Slime (Slim) にする

Slime

PhoenixのデフォルトのTemplate Engineは erbライクなeexです。 RailsだとerbよりSlimを使うケースも多いと思いますが、 PhoenixでもSlimライクなTemplate Engineが存在しました。

その名もSlimeです。ロゴがスライムっぽいですね。

github.com

多分発音も"スリム"じゃなくて"スライム"だと思います。

Phoenixに適用する

基本設定

適当なPhoenixのプロジェクトの mix.exs に依存関係を追記します。

...
  defp deps do
    [{:phoenix, "~> 1.2.1"},
     {:phoenix_pubsub, "~> 1.0"},
     {:phoenix_ecto, "~> 3.0"},
     {:postgrex, ">= 0.0.0"},
     {:phoenix_html, "~> 2.6"},
     {:phoenix_live_reload, "~> 1.0", only: :dev},
     {:gettext, "~> 0.11"},
     {:cowboy, "~> 1.0"},
     {:phoenix_slime, "~> 0.6.0"} # here
   ]
  end

config/config.exs にも適当に設定書きます。

# Configure slime
config :phoenix, :template_engines,
  slim: PhoenixSlime.Engine,
  slime: PhoenixSlime.Engine

依存関係を追記したので本体をfetchしてきます

$ mix deps.get

watch対象に追加

my_app/config/dev.exs を修正。ライブリロードを有効にするために、slim, slimeのファイルをwatch対象に追加します。

# Watch static and templates for browser reloading.
config :slime_sample, SlimeSample.Endpoint,
  live_reload: [
    patterns: [
      ~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
      ~r{priv/gettext/.*(po)$},
      ~r{web/views/.*(ex)$},
      ~r{web/templates/.*(eex|slim|slime)$} # here
    ]
  ]

Generator Tasks

$ mix help | grep -i phoenix

とすると、phoenix関係のmix taskがドバドバ表示されます。

$ mix help | grep -i phoenix
mix local.phoenix            # Updates Phoenix locally
mix phoenix.digest           # Digests and compress static files
mix phoenix.gen.channel      # Generates a Phoenix channel
mix phoenix.gen.html         # Generates controller, model and views for an HTML based resource
mix phoenix.gen.html.slime   # Generates controller, model and views for an HTML based resource using Slime templates
mix phoenix.gen.json         # Generates a controller and model for a JSON based resource
mix phoenix.gen.layout.slime # Generates a default Phoenix layout file in Slime
mix phoenix.gen.model        # Generates an Ecto model
mix phoenix.gen.presence     # Generates a Presence tracker
mix phoenix.gen.secret       # Generates a secret
mix phoenix.new              # Creates a new Phoenix v1.2.1 application
mix phoenix.routes           # Prints all routes
mix phoenix.server           # Starts applications and their servers

出てこない場合は mix compile なり mix phoenix.routes なりすると buildが走って一緒にtaskが生成されると思います。

slime関係で新しくできたtaskは

mix phoenix.gen.html.slime   # Generates controller, model and views for an HTML based resource using Slime templates
mix phoenix.gen.layout.slime # Generates a default Phoenix layout file in Slime

の2つです。

とりあえず動かしてみます。

User users と書いている部分は 単数形 複数形 で入力します。 生成されるcontroller名はrailsと違って単数形ですね。

$ mix phoenix.gen.html.slime User users --no-model
* creating web/controllers/user_controller.ex
* creating web/views/user_view.ex
* creating test/controllers/user_controller_test.exs
* creating web/templates/user/edit.html.slim
* creating web/templates/user/form.html.slim
* creating web/templates/user/index.html.slim
* creating web/templates/user/new.html.slim
* creating web/templates/user/show.html.slim

Add the resource to your browser scope in web/router.ex:

    resources "/users", UserController

見事にslimファイルが生成されましたね。slimeはどこに行ったんでしょうか。

生成されたslimの中身は以下のようになってます。

h2 Listing users

table.table
  thead
    tr
      th
  tbody
    = for user <- @users do
      tr
        td class="text-right"
          = link "Show", to: user_path(@conn, :show, user), class: "btn btn-default btn-xs"
          | &nbsp;
          = link "Edit", to: user_path(@conn, :edit, user), class: "btn btn-default btn-xs"
          | &nbsp;
          = link "Delete", to: user_path(@conn, :delete, user), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs"

= link "New user", to: user_path(@conn, :new)

ページの表示

とりあえずメッセージの通りに web/router.exresources "/users", UserController を追記します。

--no-model にしたせいかサーバ起動しようとするとめっちゃ怒られるので user_controller の余計なアクションを一旦全部削って以下のようにします。

defmodule SlimeSample.UserController do
  use SlimeSample.Web, :controller

  alias SlimeSample.User

  def index(conn, _params) do
    render(conn, "index.html", users: [])
  end
end

[error] Postgrex.Protocol (#PID<0.212.0>) failed to connect: ** (Postgrex.Error) FATAL (invalid_catalog_name): database "slime_sample_dev" does not exist みたいなエラーが出てきます。 DB作ってないので $ mix ecto.create で作りましょう。

とりあえずこれで

$ mix phoenix.server

して、 http://localhost:4000/users にアクセスすれば、ページが表示されるかと思います。

f:id:shotat_jp:20160921234438p:plain

Railsで作ったアプリケーションをPhoenixに移植するのが捗ります。

プログラミングElixir

プログラミングElixir

Programming Phoenix: Productive, Reliable, Fast

Programming Phoenix: Productive, Reliable, Fast

slimeのsyntax highlightのvimプラグインは提供されているようです。

github.com