Blob


1 (ns blog.templates
2 (:require [blog.time :as time]
3 [hiccup.page :refer [html5 include-css]]
4 [commonmark-hiccup.core :refer [markdown->hiccup default-config]]))
6 (defn link-item [{:keys [url text]}]
7 [:li [:a {:href url} text]])
9 (defn header [{:keys [tags]}]
10 (list
11 [:header
12 [:nav
13 [:ul
14 (link-item {:url "/", :text "Home"})
15 (link-item {:url "/tags.html", :text "All Tags"})]]
16 [:div
17 [:h1 [:a {:href "/"} "yumh"]]
18 [:p "writing about things, sometimes."]]]))
20 (defn with-page
21 [{:keys [title class], :as d} & body]
22 (html5 {:lang "en"}
23 [:head
24 [:meta {:charset "utf8"}]
25 [:meta {:name "viewport", :content "width=device-width, initial-scale=1"}]
26 [:link {:rel "shortcut icon", :href "/favicon.ico"}]
27 [:link {:rel "alternative" :type "application/rss+xml" :href "https://www.omarpolo.com/rss.xml"}]
28 [:title title]
29 (include-css "/css/style.css")]
30 [:body {:class (or class "")}
31 (header d)
32 [:main body]
33 [:footer
34 [:p "Blog powered by "
35 [:code "(clojure)"]]]]))
37 (defn post-fragment
38 [{:keys [full? title-with-link?]}
39 {:keys [title date slug tags short body], :as post}]
40 [:article
41 [:header
42 [:h1 (if title-with-link?
43 [:a {:href (str "/post/" slug ".html")} title]
44 title)]
45 [:p.author "Written by " [:em "Omar Polo"] " on " (time/fmt-loc date)]
46 [:ul.tags (map #(vector :li [:a {:href (str "/tag/" (name %) ".html")}
47 (str "#" (name %))])
48 tags)]]
49 [:section
50 (if full?
51 (markdown->hiccup default-config body)
52 [:p short])]])
54 (defn home-page
55 [{:keys [posts has-next has-prev nth]}]
56 (with-page {:title "Home"}
57 (map (partial post-fragment {:title-with-link? true})
58 posts)
59 [:nav.post-navigation
60 (if has-prev
61 [:a.prev {:href (str "/" (if (= (dec nth) 1)
62 "index"
63 (dec nth)) ".html")}
64 "« Newer Posts"])
65 (if has-next
66 [:a.next {:href (str "/" (inc nth) ".html")}
67 "Older Posts »"])]))
69 (defn post-page
70 [{:keys [title], :as post}]
71 (with-page {:title title
72 :class "article"}
73 (post-fragment {:full? true}
74 post)))
76 (defn tags-page
77 [tags]
78 (with-page {:title "All tags"
79 :class "tags"}
80 [:h2 "All tags"]
81 [:nav
82 [:ul
83 (map #(vector :li [:a {:href (str "/tag/" (name %) ".html")} (str "#" (name %))])
84 (sort (fn [a b]
85 (compare (.toLowerCase (name a))
86 (.toLowerCase (name b)))) tags))]]))
88 (defn tag-page
89 [tag posts]
90 (with-page {:title (str "Posts tagged with #" tag)
91 :class "tag"}
92 [:h2 "Post tagged with " [:code "#" tag]]
93 (map (partial post-fragment {:title-with-link? true})
94 (->> posts
95 (sort-by :date)
96 (reverse)))))