接續昨天的進度,現在我們有一個乾淨的Phoenix專案
首先來新增一個靜態頁面
打開lib/hello_phoenix/web/router.ex
這個檔案是專案的路由
所謂的路由,就是決定網址如何對應到程式的對照表
通常是對照到控制器(controller)(在Django就是對照到View)
defmodule HelloWeb.Router do
use HelloWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", HelloWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
end
# Other scopes may use custom stacks.
# scope "/api", HelloWeb do
# pipe_through :api
# end
end
如果你大致瀏覽一下,可能會注意到pipeline :browser
與pipeline :api
我個人認為這是相當好的發明
因為這邊算是新手指引,所以先不解釋太多
簡言之,就是讓透過瀏覽器與API兩種不同的進入專案模式可以做不同的處理
後面有機會再詳細說明。
我們讀到這一行get "/", PageController, :index
這就是我們看到的預設首頁的路由
我覺得能看到是蠻好的,有助於新手了解來龍去脈
像是Rails的預設首頁路由與內容都是藏在底層運作
也難怪很多人會說Rails充滿著黑魔法(不知道為什麼,但是會動)
要新增頁面,我們先建立一個路由
在首頁的路由下面新增這樣一行:get "/hello", HelloController, :index
如果你之前碰過任何一種現代網站框架,你大概就已經能理解這一行在講什麼:
當GET
方法訪問 http://localhost:4000/hello 的時候
對應到HelloController
的index
方法
也就是上面提到的網址與控制器的對應關係
順帶一提,透過在瀏覽器輸入網址的訪問,就是GET
方法
如果要模擬POST
或其他方法(通常是測試API時),可以透過一些工具
很遺憾的,當你新增完路由以後,controller不會自己產生
你可以透過指令或是手動新增檔案,這邊我們先手動新增
建立lib/hello_phoenix/web/controllers/hello_controller.ex
然後把下面內容複製貼上:
# hello_controller.ex
defmodule HelloWeb.HelloController do
use HelloWeb, :controller
def index(conn, _params) do
render conn, "index.html"
end
end
這邊稍微說明一下命名慣例
你可能會好奇為什麼在路由與程式內我們使用HelloController
但是檔案名稱卻是hello_controller
沒有為什麼,這就是慣例(XD)
首字大寫的組合叫做「駝峰式命名」(Upper Camel Case)
也可稱為「帕斯卡命名」(Pascal Case)
另外一種全小寫,用底線連結的我不知道怎麼稱呼(如果你知道請告訴我!)
如果你符合慣例,程式就會自動找到對應的檔案
這樣的慣例在Rails也相同
如果你硬要不符合慣例,也可以在後面指定路徑讓程式知道去哪裡找
但是建議千萬不要這麼做,只是增加維護的困擾
新增完controller後,我們接下來新增對應的view
請在 lib/hello_web/views/hello_view.ex
這個位置
複製貼上下方的程式碼:
defmodule HelloWeb.HelloView do
use HelloWeb, :view
end
最後在 lib/hello_phoenix/web/templates
新增一個新的資料夾 hello
在裡面新增一個檔案 index.html.eex
,複製貼上:
<div class="jumbotron">
<h2>Hello World, from Phoenix!</h2>
</div>
然後在瀏覽器輸入 http://localhost:4000/hello
你就可以看到
在Phoenix修改程式,是不需要重新啟動伺服器的
這一點相當方便
現在我們新增另外一個頁面,可以從網址接收參數
首先打開路由,在剛剛的hello下新增一行:
scope "/", HelloWeb do
pipe_through :browser # Use the default browser stack.
get "/", PageController, :index
get "/hello", HelloController, :index
get "/hello/:messenger", HelloController, :show
end
接著到剛剛的hello_controller.ex
新增show
方法:
def show(conn, %{"messenger" => messenger}) do
render conn, "show.html", messenger: messenger
end
最後一個動作,在剛剛的hello資料夾下新增一個show.html.eex
<div class="jumbotron">
<h2>Hello World, from <%= @messenger %>!</h2>
</div>
好了!現在如果我們打開瀏覽器,輸入 http://localhost:4000/hello/bater
基本上在hello後面的參數不管接什麼名字,都會呈現在畫面上
現在回頭說明一下什麼是 *.html.eex
eex
就是Elixir會事先編譯的文件,前面有html
代表是Elixir編譯過後會產生HTML
在這樣的文件內可使用Elixir語法,跟Ruby的erb一模一樣
<%= %>
這樣的開頭結尾之中的Elixir語法會執行,而且會輸出<% %>
這樣也會執行,但是不會輸出剛剛新增了兩條新路由,你可能還沒有感覺
但之後如果每次有新的功能就要新增一次路由
感覺非常麻煩
所以Phoenix跟Rails一樣有resources
懶人工具
他會一次幫你產生八個常用到的路由
比如說:
resources "/users", UserController
他會自動產生下面的路由
user_path GET /users HelloPhoenix.UserController :index
user_path GET /users/:id/edit HelloPhoenix.UserController :edit
user_path GET /users/new HelloPhoenix.UserController :new
user_path GET /users/:id HelloPhoenix.UserController :show
user_path POST /users HelloPhoenix.UserController :create
user_path PATCH /users/:id HelloPhoenix.UserController :update
PUT /users/:id HelloPhoenix.UserController :update
user_path DELETE /users/:id HelloPhoenix.UserController :delete
順帶一提,如果你想查詢目前有什麼路由,指令是:
$ mix phoenix.routes
相當於Rails的
$ rake routes
恩,Rails還是比較簡短優雅呀!
當然,如果你用不到這麼多
與Rails相同,這邊也是支援only
與except
假如你輸入 resources "posts", PostController, only: [:index, :show]
那麼就只會產生:
post_path GET /posts HelloPhoenix.PostController :index
post_path GET /posts/:id HelloPhoenix.PostController :show
resources也支援套疊,後面scope與指定controller方法都與rails大同小異
實在沒有動力複製貼上
有興趣的朋友在需要用到時可以查詢用法
(看Rails的路由教學可能也有相同的效果XD)