Article list view (#12)
* Add article list view * Add article view CSS * Cleanup scaffold app layout Most importantly, fix issue with page title. * Add article view to Page controller * Add article list view to router
This commit is contained in:
parent
f17558daaf
commit
84f4b8007a
6 changed files with 184 additions and 45 deletions
122
assets/app.css
122
assets/app.css
|
|
@ -7,7 +7,7 @@
|
||||||
html {
|
html {
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
background-color: var(--bgcolor);
|
background-color: var(--bgcolor);
|
||||||
background-image: linear-gradient(#000, #201 50%);
|
background-image: linear-gradient(#000, #201 333px);
|
||||||
font:
|
font:
|
||||||
normal small/1.5 apple-system,
|
normal small/1.5 apple-system,
|
||||||
system-ui,
|
system-ui,
|
||||||
|
|
@ -21,6 +21,7 @@ html {
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
|
|
@ -42,8 +43,11 @@ h3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
background-color: #000;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 33em;
|
max-width: 40em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flx {
|
.flx {
|
||||||
|
|
@ -59,17 +63,31 @@ main {
|
||||||
margin: 1em auto;
|
margin: 1em auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75em;
|
gap: 0.5em;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
padding: 1em 2em;
|
padding: 0.5em 1em;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background-color: rgba(128, 128, 128, 0.1);
|
background-color: rgba(128, 128, 128, 0.1);
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
background-color: rgba(128, 128, 128, 0.25);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> :nth-child(even) {
|
> :nth-child(even) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.landing {
|
.landing {
|
||||||
|
|
@ -78,12 +96,100 @@ main {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #000;
|
|
||||||
padding: 3em;
|
padding: 3em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
gap: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
.breadcrumbs {
|
||||||
color: #fff;
|
list-style: none;
|
||||||
text-decoration: none;
|
padding-left: 0;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
display: inline;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: " /";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.article {
|
||||||
|
font-size: large;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
> pre {
|
||||||
|
margin: 2em 0;
|
||||||
|
background-color: #022;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0.33em;
|
||||||
|
box-shadow: 4px 4px 0 #333;
|
||||||
|
position: relative;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-size: 0.8em;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.25em;
|
||||||
|
right: 0.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> footer {
|
||||||
|
font-style: italic;
|
||||||
|
text-align: right;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: "JetBrains mono", monaco, menlo, meslo, "Courier New", Courier,
|
||||||
|
monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.months {
|
||||||
|
grid-auto-flow: column;
|
||||||
|
display: grid;
|
||||||
|
list-style: none;
|
||||||
|
grid-template-rows: repeat(6, 1fr);
|
||||||
|
gap: 0.5em;
|
||||||
|
padding-left: 0;
|
||||||
|
margin: 3em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section > h2 {
|
||||||
|
background: #000;
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.articles {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 3em;
|
||||||
|
grid-auto-rows: 1fr;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
border-top: 6px solid red;
|
||||||
|
|
||||||
|
&:focus-within {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
date {
|
||||||
|
border-top: 1px solid crimson;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,17 @@
|
||||||
<b>madr</b><br>
|
<main>
|
||||||
|> Hårdrock<br>
|
<%= @inner_content %>
|
||||||
|> Programmering<br>
|
</main>
|
||||||
|> Ljudteknik<br>
|
<!--
|
||||||
|> Åsikter
|
|
||||||
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/om">Om mig</a></li>
|
|
||||||
<li><a href="/webblogg">Webblogg</a></li>
|
|
||||||
<li><a href="/delningar">Delningar</a></li>
|
|
||||||
<li><a href="/evenemang">Evenemang</a></li>
|
|
||||||
<li><a href="/vad-jag-gor">Vad jag gör</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<form metod="get" action="/search">
|
|
||||||
<label>Search site <input type="search" name="q"></label>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/madr" rel="external">Github</a></li>
|
|
||||||
<li><a href="https://linkedin.com/anders-ytterstrom" rel="external">LinkedIn</a></li>
|
|
||||||
<li><a href="https://discogs.com/madr" rel="external">Discogs</a></li>
|
|
||||||
<li><a href="https://songkick.com/madr" rel="external">Songkick</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<%= @inner_content %>
|
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<p><a href="https://madr.se" rel="home">madr.se</a> av Anders Englöf Ytterström, sedan 2006. <a href="/colophon">Kolofon</a>.</p>
|
<p>
|
||||||
|
<a href="https://madr.se" rel="home">madr.se</a>
|
||||||
|
av Anders Englöf Ytterström, sedan 2006. <a href="/colophon">Kolofon</a>.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://github.com/madr" rel="external">Github</a></li>
|
||||||
|
<li><a href="https://linkedin.com/anders-ytterstrom" rel="external">LinkedIn</a></li>
|
||||||
|
<li><a href="https://discogs.com/madr" rel="external">Discogs</a></li>
|
||||||
|
<li><a href="https://songkick.com/madr" rel="external">Songkick</a></li>
|
||||||
|
</ul>
|
||||||
</footer>
|
</footer>
|
||||||
|
-->
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<meta name="csrf-token" content={get_csrf_token()} />
|
<meta name="csrf-token" content={get_csrf_token()} />
|
||||||
<.live_title suffix=" · Phoenix Framework">
|
<title><%= assigns[:page_title] || "Anders Englöf Ytterström" %></title>
|
||||||
<%= assigns[:page_title] || "Mse25" %>
|
|
||||||
</.live_title>
|
|
||||||
<link rel="stylesheet" href={~p"/assets/app.css"} />
|
<link rel="stylesheet" href={~p"/assets/app.css"} />
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-white">
|
<body class="bg-white">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
defmodule Mse25Web.PageController do
|
defmodule Mse25Web.PageController do
|
||||||
use Mse25Web, :controller
|
use Mse25Web, :controller
|
||||||
|
|
||||||
alias Logger.Backends.Console
|
|
||||||
alias Mse25.Directus
|
alias Mse25.Directus
|
||||||
|
|
||||||
def home(conn, _params) do
|
def home(conn, _params) do
|
||||||
|
|
@ -10,6 +9,7 @@ defmodule Mse25Web.PageController do
|
||||||
upcoming_events = Directus.get_events!(limit: 1, upcoming: true)
|
upcoming_events = Directus.get_events!(limit: 1, upcoming: true)
|
||||||
|
|
||||||
render(conn, :home,
|
render(conn, :home,
|
||||||
|
page_title: "Anders Englöf Ytterström @ madr.se",
|
||||||
layout: false,
|
layout: false,
|
||||||
recent_article: most_recent_article,
|
recent_article: most_recent_article,
|
||||||
older_article: older_article,
|
older_article: older_article,
|
||||||
|
|
@ -17,4 +17,20 @@ defmodule Mse25Web.PageController do
|
||||||
upcoming: upcoming_events
|
upcoming: upcoming_events
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def articles(conn, _params) do
|
||||||
|
articles = Directus.get_articles!(limit: 9999) |> group_annually
|
||||||
|
|
||||||
|
render(conn, :articles,
|
||||||
|
page_title: "Webblogg",
|
||||||
|
articles: articles
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp group_annually(items) do
|
||||||
|
items
|
||||||
|
|> Enum.group_by(fn %{"slug" => slug} -> String.slice(slug, 0..3) end)
|
||||||
|
|> Map.to_list()
|
||||||
|
|> Enum.sort(fn {a, _a}, {b, _b} -> b < a end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
36
lib/mse25_web/controllers/page_html/articles.html.heex
Normal file
36
lib/mse25_web/controllers/page_html/articles.html.heex
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<header>
|
||||||
|
<ol class="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
|
||||||
|
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
|
||||||
|
<a href="/" rel="home">
|
||||||
|
<span itemprop="name">madr.se</span>
|
||||||
|
</a>
|
||||||
|
<meta itemprop="position" content="1" />
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<h1>Webblogg</h1>
|
||||||
|
<p>
|
||||||
|
Inlägg skrivna sedan 2006. Gå direkt till:
|
||||||
|
</p>
|
||||||
|
<ul class="months">
|
||||||
|
<%= for {year, articles} <- @articles do %>
|
||||||
|
<li>
|
||||||
|
<a href={"#y" <> year}><%= year %></a> (<%= Enum.count(articles) %>)
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<%= for {year, articles} <- @articles do %>
|
||||||
|
<section id={"y" <> year}>
|
||||||
|
<h2 class="sticky"><%= year %></h2>
|
||||||
|
<div class="articles">
|
||||||
|
<%= for article <- articles do %>
|
||||||
|
<article>
|
||||||
|
<h2>
|
||||||
|
<a href={"/" <> article["slug"]}><%= article["title"] %></a>
|
||||||
|
</h2>
|
||||||
|
<date><%= article["pubDate"] %></date>
|
||||||
|
</article>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
|
</header>
|
||||||
|
|
@ -23,11 +23,9 @@ defmodule Mse25Web.Router do
|
||||||
# get "/kommande-evenemang.ics", EventController, :calendar
|
# get "/kommande-evenemang.ics", EventController, :calendar
|
||||||
# get "/event-map.js", EventController, :interactive_map
|
# get "/event-map.js", EventController, :interactive_map
|
||||||
|
|
||||||
# get "/webblogg", ArticleController, :index
|
get "/webblogg", PageController, :articles
|
||||||
# get "/webblogg/prenumerera.xml", ArticleController, :feed
|
|
||||||
|
|
||||||
# get "/delningar", ShareController, :index
|
# get "/delningar", ShareController, :index
|
||||||
# get "/delningar/prenumerera.xml", ShareController, :feed
|
|
||||||
|
|
||||||
# get "/:year", TimelineController, :annual
|
# get "/:year", TimelineController, :annual
|
||||||
# get "/prenumerera.xml", TimelineController, :feed
|
# get "/prenumerera.xml", TimelineController, :feed
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue