Browse Source

feat: first version of blog posts and notes

master
Inhji Y. 10 months ago
parent
commit
0006da6073
  1. 6
      apps/blog/lib/blog.ex
  2. 11
      apps/blog/lib/blog/post.ex
  3. 46
      apps/tomie_web/lib/tomie_web/controllers/blog_controller.ex
  4. 7
      apps/tomie_web/lib/tomie_web/router.ex
  5. 3
      apps/tomie_web/lib/tomie_web/templates/blog/edit.html.eex
  6. 12
      apps/tomie_web/lib/tomie_web/templates/blog/form.html.eex
  7. 28
      apps/tomie_web/lib/tomie_web/templates/blog/index.html.eex
  8. 3
      apps/tomie_web/lib/tomie_web/templates/blog/new.html.eex
  9. 7
      apps/tomie_web/lib/tomie_web/templates/layout/navigation.html.eex
  10. 3
      apps/tomie_web/lib/tomie_web/views/blog_view.ex
  11. 8
      apps/tomie_web/lib/tomie_web/views/icon_view.ex
  12. 1
      apps/tomie_web/mix.exs

6
apps/blog/lib/blog.ex

@ -26,8 +26,10 @@ defmodule Blog do
Db.Repo.get!(Post, id)
|> Db.Repo.preload(@preloads)
def list_posts() do
%Post{}
def list_posts(limit \\ 10) do
Post
|> where(type: "post")
|> limit(^limit)
|> Db.Repo.all()
|> Db.Repo.preload(@preloads)
end

11
apps/blog/lib/blog/post.ex

@ -33,7 +33,7 @@ defmodule Blog.Post do
|> cast(attrs, [
:source,
:title,
:content,
:content_html,
:views,
:viewed_at,
:is_favorite,
@ -41,7 +41,14 @@ defmodule Blog.Post do
:is_archived
])
|> maybe_set_tag_string()
|> validate_required([:source, :type])
|> validate_required([:content_html, :type])
end
def subtype(post) do
case post.title do
nil -> :note
_ -> :article
end
end
# This function requires tags to be preloaded!

46
apps/tomie_web/lib/tomie_web/controllers/blog_controller.ex

@ -0,0 +1,46 @@
defmodule TomieWeb.BlogController do
use TomieWeb, :controller
def index(conn, _params) do
posts = Blog.list_posts()
render(conn, "index.html", posts: posts)
end
def edit(conn, %{"id" => id}) do
post = Blog.get_post!(id)
changeset = Blog.Post.changeset(post)
render(conn, "edit.html", post: post, changeset: changeset)
end
def update(conn, %{"id" => id, "post" => post_params}) do
post = Blog.get_post!(id)
case Blog.update_post(post, post_params) do
{:ok, post} ->
conn
|> redirect(to: Routes.blog_path(conn, :index))
{:error, changeset} ->
render(conn, "edit.html", changeset: changeset)
end
end
def new(conn, _params) do
changeset = Blog.Post.changeset(%Blog.Post{})
render(conn, "new.html", changeset: changeset)
end
def create(conn, %{"post" => post_params}) do
case Blog.create_post(post_params) do
{:ok, post} ->
conn
|> redirect(to: Routes.blog_path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
end

7
apps/tomie_web/lib/tomie_web/router.ex

@ -66,6 +66,13 @@ defmodule TomieWeb.Router do
live "/", PageLive.Index
get "/posts", BlogController, :index
get "/posts/new", BlogController, :new
post "/posts/new", BlogController, :create
get "/posts/:id/edit", BlogController, :edit
post "/posts/:id/edit", BlogController, :update
put "/posts/:id/edit", BlogController, :update
live "/bookmarks", BookmarkLive.Index
live "/bookmarks/new", BookmarkLive.New
live "/bookmarks/:id", BookmarkLive.Show

3
apps/tomie_web/lib/tomie_web/templates/blog/edit.html.eex

@ -0,0 +1,3 @@
<div>
<%= render "form.html", Map.put(assigns, :action, Routes.blog_path(@conn, :update, @post)) %>
</div>

12
apps/tomie_web/lib/tomie_web/templates/blog/form.html.eex

@ -0,0 +1,12 @@
<%= form_for @changeset, @action, [multipart: true], fn f -> %>
<fieldset>
<%= text_input f, :title %>
</fieldset>
<fieldset>
<%= hidden_input f, :content_html %>
<trix-editor input="post_content_html" class="trix-content"></trix-editor>
</fieldset>
<%= submit "submit", class: "button" %>
<% end %>

28
apps/tomie_web/lib/tomie_web/templates/blog/index.html.eex

@ -0,0 +1,28 @@
<nav>
<ul>
<li>
<%= link to: Routes.blog_path(@conn, :new) do %>
<span class="icon">
<%= IconView.icon(:add_outline) %>
</span>
<span>New Post</span>
<% end %>
</li>
</ul>
</nav>
<%= for post <- @posts do %>
<article class="card">
<div class="content trix-content">
<h3><%= post.title %></h3>
<%= unless Blog.Post.subtype(post) === :article do %>
<%= raw(post.content_html) %>
<% end %>
</div>
<footer>
<%= link "Edit", to: Routes.blog_path(@conn, :edit, post.id), class: "button" %>
</footer>
</article>
<% end %>

3
apps/tomie_web/lib/tomie_web/templates/blog/new.html.eex

@ -0,0 +1,3 @@
<div>
<%= render "form.html", Map.put(assigns, :action, Routes.blog_path(@conn, :create)) %>
</div>

7
apps/tomie_web/lib/tomie_web/templates/layout/navigation.html.eex

@ -7,6 +7,13 @@
</span>
<% end %>
</li>
<li><%= active_link @conn, to: Routes.blog_path(@conn, :index) do %>
<span class="icon">
<%= IconView.icon(:blog) %>
</span>
<span>Blog</span>
<% end %>
</li>
<li><%= active_link @conn, to: Routes.live_path(TomieWeb.Endpoint, TomieWeb.BookmarkLive.Index) do %>
<span class="icon">
<%= IconView.icon(:bookmark) %>

3
apps/tomie_web/lib/tomie_web/views/blog_view.ex

@ -0,0 +1,3 @@
defmodule TomieWeb.BlogView do
use TomieWeb, :view
end

8
apps/tomie_web/lib/tomie_web/views/icon_view.ex

@ -12,6 +12,14 @@ defmodule TomieWeb.IconView do
"""
end
defp svg_icon(:blog) do
~E"""
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path d="M2 4v14h14v-6l2-2v10H0V2h10L8 4H2zm10.3-.3l4 4L8 16H4v-4l8.3-8.3zm1.4-1.4L16 0l4 4-2.3 2.3-4-4z"/>
</svg>
"""
end
defp svg_icon(:link) do
~E"""
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">

1
apps/tomie_web/mix.exs

@ -38,6 +38,7 @@ defmodule TomieWeb.MixProject do
# Type `mix help deps` for examples and options.
defp deps do
[
{:blog, in_umbrella: true},
{:bookmarks, in_umbrella: true},
{:chartkick, "~> 0.4.0"},
{:db, in_umbrella: true},

Loading…
Cancel
Save