Posted on February 17, 2016 by Clive
As I had a spare hour, I thought that I would continue on with the 'Build a blog' series. As a continuation from where we left off last time, I thought that I would tackle the issue of publishing. For those of you that like to follow along, but haven't set up the blog yet, read Building a Blog with Phoenix to get started.
The first thing that will need to happen is that the router will need to be updated with a new route. As this will require that the data in the Post model is updated, we will use the PUT HTTP verb as follows
scope "/", Blog do
pipe_through :browser # Use the default browser stack
put "/posts/:id/publish", PostController, :publish <--- Add this line
resources "/posts", PostController
get "/:url", ArticleController, :show
get "/", ArticleController, :index
end
Once this is in place, update the Post Controller by adding in a new publish action
def publish(conn, %{"id" => id}) do
post = Repo.get!(Post, id)
changeset = Post.changeset(post, %{"published" => true, "date_published" => Ecto.Date.utc})
case Repo.update(changeset) do
{:ok, post} ->
conn
|> put_flash(:info, "Published successfully.")
|> redirect(to: post_path(conn, :show, post))
{:error, _} ->
conn
|> put_flash(:error, "Didn't publish")
|> redirect(to: post_path(conn, :show, post))
end
end
Here we are passing the Post Id in the PUT request. Using this data, we are pulling the associated record into a changeset and updating it. We will cover data validation shortly. On successful update, we'll add a 'Success' message to the page flash and redirect back to the Show action. On fail, we'll do the same but with a different message.
The last thing that needs to happen is that the Show template (web/templates/post/show.html.eex) needs to be updated.
We do this as follows - to the bottom of the meta data section
<div class="col-sm-2">
<p class="small">Last Updated:</p>
</div>
<div class="col-sm-2">
<%= date_format @post.updated_at %>
</div>
</div>
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p> <-- Add this line
<p class="danger danger-info" role="alert"><%= get_flash(@conn, :info) %></p> <-- And this one
</section>
And then, add in the button at the bottom of the page
<section class="control">
<%= if not @post.published do %>
<%= link "Publish", to: post_path(@conn, :publish, @post), method: :put, class: "btn btn-danger" %>
<% end %>
...
</section>
And thats it, you can now preview and publish from the same page.
TTFN