diff --git a/lib/philomena/static_pages.ex b/lib/philomena/static_pages.ex index edb63077..8db02d76 100644 --- a/lib/philomena/static_pages.ex +++ b/lib/philomena/static_pages.ex @@ -4,9 +4,11 @@ defmodule Philomena.StaticPages do """ import Ecto.Query, warn: false + alias Ecto.Multi alias Philomena.Repo alias Philomena.StaticPages.StaticPage + alias Philomena.StaticPages.Version @doc """ Returns the list of static_pages. @@ -49,10 +51,17 @@ defmodule Philomena.StaticPages do {:error, %Ecto.Changeset{}} """ - def create_static_page(attrs \\ %{}) do - %StaticPage{} - |> StaticPage.changeset(attrs) - |> Repo.insert() + def create_static_page(user, attrs \\ %{}) do + static_page = StaticPage.changeset(%StaticPage{}, attrs) + + Multi.new() + |> Multi.insert(:static_page, static_page) + |> Multi.run(:version, fn repo, %{static_page: static_page} -> + %Version{static_page_id: static_page.id, user_id: user.id} + |> Version.changeset(attrs) + |> repo.insert() + end) + |> Repo.isolated_transaction(:serializable) end @doc """ @@ -67,10 +76,19 @@ defmodule Philomena.StaticPages do {:error, %Ecto.Changeset{}} """ - def update_static_page(%StaticPage{} = static_page, attrs) do - static_page - |> StaticPage.changeset(attrs) - |> Repo.update() + def update_static_page(%StaticPage{} = static_page, user, attrs) do + version = + %Version{static_page_id: static_page.id, user_id: user.id} + |> Version.changeset(attrs) + + static_page = + static_page + |> StaticPage.changeset(attrs) + + Multi.new() + |> Multi.update(:static_page, static_page) + |> Multi.insert(:version, version) + |> Repo.isolated_transaction(:serializable) end @doc """ diff --git a/lib/philomena/static_pages/static_page.ex b/lib/philomena/static_pages/static_page.ex index 54c8bbbc..d107d52c 100644 --- a/lib/philomena/static_pages/static_page.ex +++ b/lib/philomena/static_pages/static_page.ex @@ -15,7 +15,7 @@ defmodule Philomena.StaticPages.StaticPage do @doc false def changeset(static_page, attrs) do static_page - |> cast(attrs, []) - |> validate_required([]) + |> cast(attrs, [:title, :slug, :body]) + |> validate_required([:title, :slug, :body]) end end diff --git a/lib/philomena/static_pages/version.ex b/lib/philomena/static_pages/version.ex index f6309f83..172d0750 100644 --- a/lib/philomena/static_pages/version.ex +++ b/lib/philomena/static_pages/version.ex @@ -21,7 +21,7 @@ defmodule Philomena.StaticPages.Version do @doc false def changeset(version, attrs) do version - |> cast(attrs, []) - |> validate_required([]) + |> cast(attrs, [:title, :slug, :body]) + |> validate_required([:title, :slug, :body]) end end diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index 9a102d43..fd815603 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -15,6 +15,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do alias Philomena.UserLinks.UserLink alias Philomena.Tags.Tag alias Philomena.Reports.Report + alias Philomena.StaticPages.StaticPage alias Philomena.Bans.User, as: UserBan alias Philomena.Bans.Subnet, as: SubnetBan @@ -220,6 +221,9 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do def can?(%User{}, action, Gallery) when action in [:new, :create], do: true def can?(%User{id: id}, action, %Gallery{creator_id: id}) when action in [:edit, :update, :delete], do: true + # Show static pages + def can?(_user, :show, %StaticPage{}), do: true + # Otherwise... def can?(_user, _action, _model), do: false end diff --git a/lib/philomena_web/controllers/page/history_controller.ex b/lib/philomena_web/controllers/page/history_controller.ex index c4fadd28..f3b13f2d 100644 --- a/lib/philomena_web/controllers/page/history_controller.ex +++ b/lib/philomena_web/controllers/page/history_controller.ex @@ -24,7 +24,7 @@ defmodule PhilomenaWeb.Page.HistoryController do defp generate_differences(pages, current_body) do Enum.map_reduce(pages, current_body, fn page, previous_body -> - difference = List.myers_difference(split(previous_body), split(page.body)) + difference = List.myers_difference(split(page.body), split(previous_body)) {%{page | difference: difference}, page.body} end) @@ -32,4 +32,4 @@ defmodule PhilomenaWeb.Page.HistoryController do defp split(nil), do: "" defp split(body), do: String.split(body, "\n") -end \ No newline at end of file +end diff --git a/lib/philomena_web/controllers/page_controller.ex b/lib/philomena_web/controllers/page_controller.ex index 86a9ba97..6d330907 100644 --- a/lib/philomena_web/controllers/page_controller.ex +++ b/lib/philomena_web/controllers/page_controller.ex @@ -2,10 +2,49 @@ defmodule PhilomenaWeb.PageController do use PhilomenaWeb, :controller alias Philomena.StaticPages.StaticPage + alias Philomena.StaticPages - plug :load_resource, model: StaticPage, id_field: "slug" + plug :load_and_authorize_resource, model: StaticPage, id_field: "slug" + + def index(conn, _params) do + render(conn, "index.html") + end def show(conn, _params) do - render(conn, "show.html", static_page: conn.assigns.static_page) + render(conn, "show.html") + end + + def new(conn, _params) do + changeset = StaticPages.change_static_page(%StaticPage{}) + render(conn, "new.html", changeset: changeset) + end + + def create(conn, %{"static_page" => static_page_params}) do + case StaticPages.create_static_page(conn.assigns.current_user, static_page_params) do + {:ok, %{static_page: static_page}} -> + conn + |> put_flash(:info, "Static page successfully created.") + |> redirect(to: Routes.page_path(conn, :show, static_page)) + + {:error, :static_page, changeset, _changes} -> + render(conn, "new.html", changeset: changeset) + end + end + + def edit(conn, _params) do + changeset = StaticPages.change_static_page(conn.assigns.static_page) + render(conn, "edit.html", changeset: changeset) + end + + def update(conn, %{"static_page" => static_page_params}) do + case StaticPages.update_static_page(conn.assigns.static_page, conn.assigns.current_user, static_page_params) do + {:ok, %{static_page: static_page}} -> + conn + |> put_flash(:info, "Static page successfully updated.") + |> redirect(to: Routes.page_path(conn, :show, static_page)) + + {:error, :static_page, changeset, _changes} -> + render(conn, "edit.html", changeset: changeset) + end end end diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 6f8efeb3..fc4ef7a9 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -214,6 +214,8 @@ defmodule PhilomenaWeb.Router do resources "/image", Tag.ImageController, only: [:edit, :update, :delete], singleton: true resources "/alias", Tag.AliasController, only: [:edit, :update, :delete], singleton: true end + + resources "/pages", PageController, only: [:index, :new, :create, :edit, :update] end scope "/", PhilomenaWeb do diff --git a/lib/philomena_web/templates/layout/_header_staff_links.html.slime b/lib/philomena_web/templates/layout/_header_staff_links.html.slime index a22d40d2..2c46d9e5 100644 --- a/lib/philomena_web/templates/layout/_header_staff_links.html.slime +++ b/lib/philomena_web/templates/layout/_header_staff_links.html.slime @@ -32,7 +32,7 @@ ' Badges = if manages_static_pages?(@conn) do - = link to: "#", class: "header__link" do + = link to: Routes.page_path(@conn, :index), class: "header__link" do i.fa.fa-fw.fa-sticky-note> ' Pages diff --git a/lib/philomena_web/templates/page/_form.html.slime b/lib/philomena_web/templates/page/_form.html.slime new file mode 100644 index 00000000..94b4e012 --- /dev/null +++ b/lib/philomena_web/templates/page/_form.html.slime @@ -0,0 +1,19 @@ += form_for @changeset, @action, fn f -> + = if @changeset.action do + .alert.alert-danger + p Oops, something went wrong! Please check the errors below. + + .field + => label f, :title + = text_input f, :title, class: "input input--wide" + + .field + => label f, :slug + = text_input f, :slug, class: "input input--wide" + + .field + => label f, :body + = textarea f, :body, class: "input input--wide" + + .actions + = submit "Save", class: "button" diff --git a/lib/philomena_web/templates/page/edit.html.slime b/lib/philomena_web/templates/page/edit.html.slime new file mode 100644 index 00000000..2ac4387b --- /dev/null +++ b/lib/philomena_web/templates/page/edit.html.slime @@ -0,0 +1,3 @@ +h1 Editing static page + += render PhilomenaWeb.PageView, "_form.html", changeset: @changeset, action: Routes.page_path(@conn, :update, @static_page), conn: @conn diff --git a/lib/philomena_web/templates/page/index.html.slime b/lib/philomena_web/templates/page/index.html.slime index cce047ba..88731d64 100644 --- a/lib/philomena_web/templates/page/index.html.slime +++ b/lib/philomena_web/templates/page/index.html.slime @@ -1,26 +1,14 @@ -section.phx-hero - h1 = gettext "Welcome %{name}!", name: "Philomena" - p - ' A productive web framework that - br - ' does not compromise speed or maintainability. +h1 Pages -section.row - article.column - h2 Resources - ul - li - a href="https://hexdocs.pm/phoenix/overview.html" Guides & Docs - li - a href="https://github.com/phoenixframework/phoenix" Source - li - a href="https://github.com/phoenixframework/phoenix/blob/v1.4/CHANGELOG.md" Changelog - article.column - h2 Help - ul - li - a href="https://elixirforum.com/c/phoenix-forum" Forums - li - a href="https://webchat.freenode.net/?channels=elixir-lang" #elixir-lang on Freenode IRC - li - a href="https://twitter.com/elixirphoenix" Twitter @elixirphoenix +table.table + thead + tr + th Title + + tbody + = for static_page <- @static_pages do + tr + td = link static_page.title, to: Routes.page_path(@conn, :show, static_page) + +br += link "New static page", to: Routes.page_path(@conn, :new) diff --git a/lib/philomena_web/templates/page/new.html.slime b/lib/philomena_web/templates/page/new.html.slime new file mode 100644 index 00000000..48ad0fd1 --- /dev/null +++ b/lib/philomena_web/templates/page/new.html.slime @@ -0,0 +1,3 @@ +h1 New static page + += render PhilomenaWeb.PageView, "_form.html", changeset: @changeset, action: Routes.page_path(@conn, :create), conn: @conn diff --git a/lib/philomena_web/templates/page/show.html.slime b/lib/philomena_web/templates/page/show.html.slime index ffbce361..fd938294 100644 --- a/lib/philomena_web/templates/page/show.html.slime +++ b/lib/philomena_web/templates/page/show.html.slime @@ -5,8 +5,7 @@ p == @static_page.body -= link "Revision history", to: Routes.page_history_path(@conn, :index, @static_page) +p = link "Revision history", to: Routes.page_history_path(@conn, :index, @static_page) -/- if can? :manage, StaticPage - br - => link_to 'Edit', edit_static_page_path(@static_page) += if can?(@conn, :edit, Philomena.StaticPages.StaticPage) do + p = link "Edit", to: Routes.page_path(@conn, :edit, @static_page)