Nao000のぶろぐ

蝶を追っている少年になりたい

【Elixir Phoenix】 複数のCSSを読み込む方法

目次

  1. バージョン情報
  2. 目的
  3. 環境
  4. 結論
  5. 所感

バージョン情報

Elixir: 1.8.1

Phoenix: 1.4.2

目的

任意の画面で任意のCSSを読み込ませる。

環境

Elixir 1.8.2 Phoenix 1.4.2

結論

  1. contoller側で読み込ませるCSSファイル名をリストに設定する

  2. layout_view.exで読み込ませる用関数を作成する

  3. template側で出力する 以上です。順番にコードを示します。

  4. contoller側で読み込ませるCSSファイル名をリストに設定する priv/static/css/detail.cssを読み込ませます。リストには拡張子を抜いた "detail" を設定します。blogディレクトリなどの中に作成したものを読み込ませる場合には " blog/detail "を設定します。

defmodule MyappWeb.User.BlogController do
   use MyappWeb, :controller
     def detail(conn, blog, params) do
       css = ["detail"] # <- here
       data = %{
         css: css
       }
       render(conn, "detail.html", data)
     end
end
  1. layout_view.exで関数を作成する Routes.static_path関数を使用します。デフォルトで app.html.eex でCSS,JSファイルを読み込むのに使用しています。 Routes.static_pathの公式ドキュメント探しましたが、Endpointの項目にそれらしき関数がありました。本当にこの関数なのか分かりませんでした。https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#c:static_path/1
defmodule MyappWeb.LayoutView do
 use MyappWeb, :view
   def css(conn) do
     case conn.assigns[:css] do
       nil -> ""
       # VVV here VVV
       css ->Enum.map(conn.assigns[:css], fn css -> "<link rel="stylesheet" href="<> Routes.static_path(conn, "/css/") <> css <>".css/>
" end)
     end
   end
end
  1. template側で出力する 最後に画面に出力させます。そのまま出力するとダブルクォーテーションなどがエスケープされてしまうので、raw関数を使用します。これによりエスケープされません。
 <!DOCTYPE html>
 <html>
     <head>
         <meta charset="utf-8"/>
         <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
         <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
         <title><%= title(@conn) %></title>
         <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
         <%= raw css(@conn) %> <!-- here -->
     </head>
     <body>
         ~
     </body>
</html>

所感

公式で何かしら用意されているかもですが、目的は達成することができると思います。Phoenixはデフォルトでwebpackが入っていますので、もしかしたらすべて1つのファイルにまとめることを推奨しているのかもしれません。