feat: Add basic dev server

This commit is contained in:
Robert Prehn 2024-11-30 13:01:15 -06:00
parent 6b01a1fc04
commit 680d116695
No known key found for this signature in database
7 changed files with 77 additions and 11 deletions

View file

@ -0,0 +1,8 @@
defmodule Mix.Tasks.PreDotHn.DevServer do
use Mix.Task
def run(_args) do
Application.put_env(:pre_dot_hn, :serve_endpoints, true, persistent: true)
Mix.Tasks.Run.run(["--no-halt"])
end
end

View file

@ -76,7 +76,7 @@ defmodule PreDotHn do
body =
~H"""
<%= for post <- @posts do %>
<div style="margin-bottom: 1rem">
<div :if={!post.hidden} style="margin-bottom: 1rem">
<span class="text-yellow align-top"><%= post.date %></span>&nbsp;
<a class="text-ellipsis overflow-hidden inline-block" style="max-width: 40ch" href={"/#{post.slug}/"}><%= post.title %></a>
</div>
@ -93,7 +93,7 @@ defmodule PreDotHn do
end
def make_feed(posts) do
posts = Enum.take(posts, 10)
posts = posts |> Enum.reject(& &1.hidden) |> Enum.take(10)
base = Application.get_env(:pre_dot_hn, :base, "/")
assigns = %{base: base, posts: posts}
@ -166,6 +166,9 @@ defmodule PreDotHn do
def make_sitemap(posts) do
posts
|> Stream.reject(fn %{hidden: hidden} ->
hidden
end)
|> Stream.map(
&%Sitemapper.URL{lastmod: &1[:updated_at] || &1.date, loc: "https://pre.hn/#{&1.slug}/"}
)
@ -218,10 +221,10 @@ defmodule PreDotHn do
def menu(assigns) do
~H"""
<nav class="block bg-blue text-dark">
&nbsp;<a href="/">About Me</a>
&nbsp;<a href="/blog">Blog</a>
&nbsp;<a href="/link-log">Link Log</a>
<nav class="block bg-blue text-dark flex gap-x-[0.6rem] px-[1.2rem]">
<a class="px-[0.6rem]" href="/">About Me</a>
<a class="px-[0.6rem]" href="/blog">Blog</a>
<a class="px-[0.6rem]" href="/link-log">Link Log</a>
</nav>
"""
end
@ -238,7 +241,7 @@ defmodule PreDotHn do
~H"""
<.layout title={@title} slug={@slug} description={assigns[:description]}>
<main class="container mx-auto">
<main class="container mx-auto py-[2.6rem]">
<section class="box border border-light">
<h1><%= @title %></h1>
<%= {:safe, @body} %>

View file

@ -0,0 +1,12 @@
defmodule PreDotHn.Application do
use Application
def start(_type, _args) do
children = [
{Bandit, plug: PreDotDn.DevServer}
]
opts = [strategy: :one_for_one, name: PreDotHn.Supervisor]
Supervisor.start_link(children, opts)
end
end

View file

@ -0,0 +1,34 @@
defmodule PreDotDn.DevServer do
use Plug.Router
plug(Plug.Logger)
plug(:rewrite_dirs)
plug(Plug.Static, at: "", from: "priv/static")
get "/health" do
conn |> resp(200, "ok") |> halt()
end
plug(:match)
plug(:dispatch)
def rewrite_dirs(conn, _) do
is_directory =
case Enum.reverse(conn.path_info) do
[] ->
true
[last_segment | _] ->
!String.contains?(last_segment, ".")
end
if is_directory do
request_path = conn.request_path <> "index.html"
path_info = conn.path_info ++ ["index.html"]
%{conn | path_info: path_info, request_path: request_path}
else
conn
end
end
end

View file

@ -25,6 +25,9 @@ defmodule PreDotHn.Frontmatter do
|> Map.put_new_lazy("title", fn ->
""
end)
|> Map.put_new_lazy("hidden", fn ->
false
end)
end
@path_parts ~r/([0-9]{4}-[0-9]{2}-[0-9]{2})?-?(.*)?/

View file

@ -15,6 +15,7 @@ defmodule PreDotHn.MixProject do
# Run "mix help compile.app" to learn about applications.
def application do
[
mod: {PreDotHn.Application, []},
extra_applications: [:logger]
]
end
@ -33,7 +34,9 @@ defmodule PreDotHn.MixProject do
{:floki, "~> 0.34.3"},
{:html_sanitize_ex, "~> 1.4"},
{:phoenix_html, "~> 3.3.2"},
{:sitemapper, "~> 0.7.0"}
{:sitemapper, "~> 0.7.0"},
{:bandit, "~> 1.0"},
{:plug, "~> 1.16.1"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]

View file

@ -1,24 +1,27 @@
%{
"bandit": {:hex, :bandit, "1.6.0", "9cb6c67c27cecab2d0c93968cb957fa8decccb7275193c8bf33f97397b3ac25d", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "fd2491e564a7c5e11ff8496ebf530c342c742452c59de17ac0fb1f814a0ab01a"},
"castore": {:hex, :castore, "1.0.5", "9eeebb394cc9a0f3ae56b813459f990abb0a3dedee1be6b27fdb50301930502f", [:mix], [], "hexpm", "8d7c597c3e4a64c395980882d4bca3cebb8d74197c590dc272cfd3b6a6310578"},
"earmark": {:hex, :earmark, "1.4.43", "2024a0e9fe9bd5ef78fb9c87517de6c6d7deaf1cffdf6572fac3dd49cb34c433", [:mix], [], "hexpm", "958011ea938bc4018797bda3f8d0c871ab04621785bedc1e7188fb079dea2f5b"},
"earmark_parser": {:hex, :earmark_parser, "1.4.35", "437773ca9384edf69830e26e9e7b2e0d22d2596c4a6b17094a3b29f01ea65bb8", [:mix], [], "hexpm", "8652ba3cb85608d0d7aa2d21b45c6fad4ddc9a1f9a1f1b30ca3a246f0acc33f6"},
"esbuild": {:hex, :esbuild, "0.7.1", "fa0947e8c3c3c2f86c9bf7e791a0a385007ccd42b86885e8e893bdb6631f5169", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "66661cdf70b1378ee4dc16573fcee67750b59761b2605a0207c267ab9d19f13c"},
"floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"},
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.3", "67b3d9fa8691b727317e0cc96b9b3093be00ee45419ffb221cdeee88e75d1360", [:mix], [{:mochiweb, "~> 2.15 or ~> 3.1", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "87748d3c4afe949c7c6eb7150c958c2bcba43fc5b2a02686af30e636b74bccb7"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
"mochiweb": {:hex, :mochiweb, "3.2.1", "ff287e1ec653a0828f226cd5a009d52be74537dc3fc274b765525a77ce01f8ec", [:rebar3], [], "hexpm", "975466d335403a78cd58186636b8e960e3c84c4d9c1a85eb7fe53b6a5dd54de7"},
"phoenix": {:hex, :phoenix, "1.7.7", "4cc501d4d823015007ba3cdd9c41ecaaf2ffb619d6fb283199fa8ddba89191e0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "8966e15c395e5e37591b6ed0bd2ae7f48e961f0f60ac4c733f9566b519453085"},
"phoenix_html": {:hex, :phoenix_html, "3.3.2", "d6ce982c6d8247d2fc0defe625255c721fb8d5f1942c5ac051f6177bffa5973f", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "44adaf8e667c1c20fb9d284b6b0fa8dc7946ce29e81ce621860aa7e96de9a11d"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.19.5", "6e730595e8e9b8c5da230a814e557768828fd8dfeeb90377d2d8dbb52d4ec00a", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b2eaa0dd3cfb9bd7fb949b88217df9f25aed915e986a28ad5c8a0d054e7ca9d3"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
"phoenix_template": {:hex, :phoenix_template, "1.0.3", "32de561eefcefa951aead30a1f94f1b5f0379bc9e340bb5c667f65f1edfa4326", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "16f4b6588a4152f3cc057b9d0c0ba7e82ee23afa65543da535313ad8d25d8e2c"},
"plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"},
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
"rustler": {:hex, :rustler, "0.29.1", "880f20ae3027bd7945def6cea767f5257bc926f33ff50c0d5d5a5315883c084d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "109497d701861bfcd26eb8f5801fe327a8eef304f56a5b63ef61151ff44ac9b6"},
"sitemapper": {:hex, :sitemapper, "0.7.0", "4aee7930327a9a01b1c9b81d1d42f60c1a295e9f420108eb2d130c317415abd7", [:mix], [{:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "60f7a684e5e9fe7f10ac5b69f48b0be2bcbba995afafcb3c143fc0c8ef1f223f"},
"tailwind": {:hex, :tailwind, "0.2.1", "83d8eadbe71a8e8f67861fe7f8d51658ecfb258387123afe4d9dc194eddc36b0", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "e8a13f6107c95f73e58ed1b4221744e1eb5a093cd1da244432067e19c8c9a277"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
"thousand_island": {:hex, :thousand_island, "1.3.7", "1da7598c0f4f5f50562c097a3f8af308ded48cd35139f0e6f17d9443e4d0c9c5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0139335079953de41d381a6134d8b618d53d084f558c734f2662d1a72818dd12"},
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
"tree_sitter": {:hex, :tree_sitter, "0.0.2", "33218eeb40bf897f84d163a07b2373742db7dfee2e6601a60b5733fc6f33656f", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "8bf71f50a7b1d0ac4b8936fc55d50a21386b8b319f3ceb6f59f1377314e8bb5d"},
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},