repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
bc3e29b
parent
bb90d2e
author
Eric Bower
date
2022-11-07 21:18:41 +0000 UTC
feat(lists): layout support

Introduced parity with prose for different layouts.  Right now we
support "default" and "aside".
20 files changed,  +280, -68
M imgs/public/main.css
+28, -0
 1@@ -324,6 +324,22 @@ figure {
 2   flex: 1;
 3 }
 4 
 5+.layout-aside {
 6+  max-width: 50rem;
 7+}
 8+
 9+.layout-aside aside {
10+  width: 200px;
11+}
12+
13+.layout-aside img {
14+  border-radius: 5px;
15+}
16+
17+#readme {
18+  display: none;
19+}
20+
21 @media only screen and (max-width: 600px) {
22   body {
23     padding: 1rem;
24@@ -332,4 +348,16 @@ figure {
25   header {
26     margin: 0;
27   }
28+
29+  .layout-aside main {
30+    flex-direction: column;
31+  }
32+
33+  aside {
34+    display: none;
35+  }
36+
37+  #readme {
38+    display: block;
39+  }
40 }
M lists/api.go
+9, -0
 1@@ -77,6 +77,7 @@ type HeaderTxt struct {
 2 	Title    string
 3 	Bio      string
 4 	Nav      []*ListItem
 5+	Layout   string
 6 	HasItems bool
 7 }
 8 
 9@@ -140,6 +141,8 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
10 	curl := shared.CreateURLFromRequest(cfg, r)
11 
12 	ts, err := shared.RenderTemplate(cfg, []string{
13+		cfg.StaticPath("html/blog-default.partial.tmpl"),
14+		cfg.StaticPath("html/blog-aside.partial.tmpl"),
15 		cfg.StaticPath("html/blog.page.tmpl"),
16 		cfg.StaticPath("html/list.partial.tmpl"),
17 	})
18@@ -165,6 +168,10 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
19 			headerTxt.Bio = parsedText.MetaData.Description
20 		}
21 
22+		if parsedText.MetaData.Layout != "" {
23+			headerTxt.Layout = parsedText.MetaData.Layout
24+		}
25+
26 		headerTxt.Nav = parsedText.Items
27 		if len(headerTxt.Nav) > 0 {
28 			headerTxt.HasItems = true
29@@ -388,6 +395,8 @@ func transparencyHandler(w http.ResponseWriter, r *http.Request) {
30 		cfg.StaticPath("html/footer.partial.tmpl"),
31 		cfg.StaticPath("html/marketing-footer.partial.tmpl"),
32 		cfg.StaticPath("html/base.layout.tmpl"),
33+		cfg.StaticPath("html/base-aside.layout.tmpl"),
34+		cfg.StaticPath("html/base-default.layout.tmpl"),
35 	)
36 
37 	if err != nil {
M lists/html/base.layout.tmpl
+1, -1
1@@ -13,6 +13,6 @@
2 
3         <link rel="stylesheet" href="/main.css" />
4     </head>
5-    <body>{{template "body" .}}</body>
6+    <body {{template "attrs" .}}>{{template "body" .}}</body>
7 </html>
8 {{end}}
A lists/html/blog-aside.partial.tmpl
+65, -0
 1@@ -0,0 +1,65 @@
 2+{{define "blog-aside"}}
 3+<main class="flex">
 4+    <section class="flex-1 mr">
 5+        <div>
 6+            <h1 class="text-2xl font-bold">{{.Header.Title}}</h1>
 7+            {{if .Header.Bio}}<span>{{.Header.Bio}}</span>{{end}}
 8+        </div>
 9+
10+        <div id="readme">
11+            {{if .Readme.HasItems}}
12+            <section>
13+                <article>
14+                    {{template "list" .Readme}}
15+                </article>
16+                <hr />
17+            </section>
18+            {{end}}
19+
20+            <div>
21+                {{range .Header.Nav}}
22+                    {{if .IsURL}}
23+                    <a href="{{.URL}}" class="text-lg">{{.Value}}</a> |
24+                    {{end}}
25+                {{end}}
26+                <a href="{{.RSSURL}}" class="text-lg">rss</a>
27+            </div>
28+            <hr />
29+        </div>
30+
31+        {{if .HasFilter}}
32+            <a href={{.URL}}>clear filters</a>
33+        {{end}}
34+
35+        <div class="posts">
36+        {{range .Posts}}
37+            <article class="my">
38+                <div class="flex items-center">
39+                    <time datetime="{{.PublishAtISO}}" class="font-italic text-sm post-date">{{.PublishAt}}</time>
40+                    <div class="font-bold flex-1"><a href="{{.URL}}">{{.Title}}</a></div>
41+                </div>
42+            </article>
43+        {{end}}
44+        </div>
45+    </section>
46+
47+    <aside>
48+        {{if .Readme.HasItems}}
49+        <section>
50+            <article>
51+                {{template "list" .Readme}}
52+            </article>
53+        </section>
54+        {{end}}
55+
56+        <nav>
57+            {{range .Header.Nav}}
58+                {{if .IsURL}}
59+                <a href="{{.URL}}" class="text-lg">{{.Value}}</a> ยท
60+                {{end}}
61+            {{end}}
62+            <a href="{{.RSSURL}}" class="text-lg">rss</a>
63+        </nav>
64+    </aside>
65+</main>
66+{{end}}
A lists/html/blog-default.partial.tmpl
+39, -0
 1@@ -0,0 +1,39 @@
 2+{{define "blog-default"}}
 3+<header class="text-center">
 4+    <h1 class="text-2xl font-bold">{{.Header.Title}}</h1>
 5+    {{if .Header.Bio}}<p class="text-lg">{{.Header.Bio}}</p>{{end}}
 6+    <nav>
 7+        {{range .Header.Nav}}
 8+            {{if .IsURL}}
 9+            <a href="{{.URL}}" class="text-lg">{{.Value}}</a> |
10+            {{end}}
11+        {{end}}
12+        <a href="{{.RSSURL}}" class="text-lg">rss</a>
13+    </nav>
14+    <hr />
15+</header>
16+<main>
17+    {{if .Readme.HasItems}}
18+    <section>
19+        <article>
20+            {{template "list" .Readme}}
21+        </article>
22+        <hr />
23+    </section>
24+    {{end}}
25+
26+    <section class="posts">
27+        {{if .HasFilter}}
28+            <a href="{{.URL}}">clear filters</a>
29+        {{end}}
30+        {{range .Posts}}
31+        <article class="my">
32+            <div class="flex items-center">
33+                <time datetime="{{.UpdatedAtISO}}" class="font-italic text-sm post-date">{{.UpdatedTimeAgo}}</time>
34+                <div class="font-bold flex-1"><a href="{{.URL}}">{{.Title}}</a></div>
35+            </div>
36+        </article>
37+        {{end}}
38+    </section>
39+</main>
40+{{end}}
M lists/html/blog.page.tmpl
+8, -36
 1@@ -23,43 +23,15 @@
 2 <meta name="twitter:image:src" content="https://{{.Site.Domain}}/card.png" />
 3 {{end}}
 4 
 5+{{define "attrs"}}id="blog" class="layout-{{.Header.Layout}}"{{end}}
 6+
 7 {{define "body"}}
 8-<header class="text-center">
 9-    <h1 class="text-2xl font-bold">{{.Header.Title}}</h1>
10-    {{if .Header.Bio}}<p class="text-lg">{{.Header.Bio}}</p>{{end}}
11-    <nav>
12-        {{range .Header.Nav}}
13-            {{if .IsURL}}
14-            <a href="{{.URL}}" class="text-lg">{{.Value}}</a> |
15-            {{end}}
16-        {{end}}
17-        <a href="{{.RSSURL}}" class="text-lg">rss</a>
18-    </nav>
19-    <hr />
20-</header>
21-<main>
22-    {{if .Readme.HasItems}}
23-    <section>
24-        <article>
25-            {{template "list" .Readme}}
26-        </article>
27-        <hr />
28-    </section>
29-    {{end}}
30 
31-    <section class="posts">
32-        {{if .HasFilter}}
33-            <a href="{{.URL}}">clear filters</a>
34-        {{end}}
35-        {{range .Posts}}
36-        <article class="my">
37-            <div class="flex items-center">
38-                <time datetime="{{.UpdatedAtISO}}" class="font-italic text-sm post-date">{{.UpdatedTimeAgo}}</time>
39-                <div class="font-bold flex-1"><a href="{{.URL}}">{{.Title}}</a></div>
40-            </div>
41-        </article>
42-        {{end}}
43-    </section>
44-</main>
45+{{if eq .Header.Layout "aside"}}
46+    {{template "blog-aside" .}}
47+{{else}}
48+    {{template "blog-default" .}}
49+{{end}}
50+
51 {{template "footer" .}}
52 {{end}}
M lists/html/help.page.tmpl
+2, -0
1@@ -6,6 +6,8 @@
2 <meta name="description" content="questions and answers" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header>
9     <h1 class="text-2xl">Need help?</h1>
M lists/html/marketing.page.tmpl
+2, -0
1@@ -24,6 +24,8 @@
2 <meta property="og:image" content="https://{{.Site.Domain}}/card.png" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header class="text-center">
9     <h1 class="text-2xl font-bold">{{.Site.Domain}}</h1>
M lists/html/post.page.tmpl
+2, -0
1@@ -23,6 +23,8 @@
2 <meta name="twitter:image:src" content="https://{{.Site.Domain}}/card.png" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header>
9     <h1 class="text-2xl font-bold">{{.Title}}</h1>
M lists/html/privacy.page.tmpl
+2, -0
1@@ -6,6 +6,8 @@
2 <meta name="description" content="{{.Site.Domain}} privacy policy" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header>
9     <h1 class="text-2xl">Privacy</h1>
M lists/html/read.page.tmpl
+2, -0
1@@ -6,6 +6,8 @@
2 <meta name="description" content="discover interesting lists" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header class="text-center">
9     <h1 class="text-2xl font-bold">read</h1>
M lists/html/spec.page.tmpl
+2, -0
1@@ -6,6 +6,8 @@
2 <meta name="description" content="a specification for lists" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header>
9     <h1 class="text-2xl">Plain text list</h1>
M lists/html/transparency.page.tmpl
+2, -0
1@@ -6,6 +6,8 @@
2 <meta name="description" content="full transparency of analytics and cost at {{.Site.Domain}}" />
3 {{end}}
4 
5+{{define "attrs"}}{{end}}
6+
7 {{define "body"}}
8 <header>
9     <h1 class="text-2xl">Transparency</h1>
M lists/parser.go
+4, -0
 1@@ -35,6 +35,7 @@ type MetaData struct {
 2 	PublishAt   *time.Time
 3 	Title       string
 4 	Description string
 5+	Layout      string
 6 	Tags        []string
 7 	ListType    string // https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type
 8 }
 9@@ -101,6 +102,8 @@ func TokenToMetaField(meta *MetaData, token *SplitToken) {
10 		for _, tag := range tags {
11 			meta.Tags = append(meta.Tags, strings.TrimSpace(tag))
12 		}
13+	} else if token.Key == "layout" {
14+		meta.Layout = token.Value
15 	}
16 }
17 
18@@ -179,6 +182,7 @@ func ParseText(text string) *ParsedText {
19 	meta := MetaData{
20 		ListType: "disc",
21 		Tags:     []string{},
22+		Layout:   "default",
23 	}
24 	pre := false
25 	skip := false
M lists/public/main.css
+28, -0
 1@@ -324,6 +324,22 @@ figure {
 2   flex: 1;
 3 }
 4 
 5+.layout-aside {
 6+  max-width: 50rem;
 7+}
 8+
 9+.layout-aside aside {
10+  width: 200px;
11+}
12+
13+.layout-aside img {
14+  border-radius: 5px;
15+}
16+
17+#readme {
18+  display: none;
19+}
20+
21 @media only screen and (max-width: 600px) {
22   body {
23     padding: 1rem;
24@@ -332,4 +348,16 @@ figure {
25   header {
26     margin: 0;
27   }
28+
29+  .layout-aside main {
30+    flex-direction: column;
31+  }
32+
33+  aside {
34+    display: none;
35+  }
36+
37+  #readme {
38+    display: block;
39+  }
40 }
M pastes/public/main.css
+28, -0
 1@@ -324,6 +324,22 @@ figure {
 2   flex: 1;
 3 }
 4 
 5+.layout-aside {
 6+  max-width: 50rem;
 7+}
 8+
 9+.layout-aside aside {
10+  width: 200px;
11+}
12+
13+.layout-aside img {
14+  border-radius: 5px;
15+}
16+
17+#readme {
18+  display: none;
19+}
20+
21 @media only screen and (max-width: 600px) {
22   body {
23     padding: 1rem;
24@@ -332,4 +348,16 @@ figure {
25   header {
26     margin: 0;
27   }
28+
29+  .layout-aside main {
30+    flex-direction: column;
31+  }
32+
33+  aside {
34+    display: none;
35+  }
36+
37+  #readme {
38+    display: block;
39+  }
40 }
M prose/api.go
+0, -1
1@@ -463,7 +463,6 @@ func transparencyHandler(w http.ResponseWriter, r *http.Request) {
2 
3 	ts, err := template.ParseFiles(
4 		cfg.StaticPath("html/transparency.page.tmpl"),
5-		cfg.StaticPath("html/base.layout.tmpl"),
6 		cfg.StaticPath("html/footer.partial.tmpl"),
7 		cfg.StaticPath("html/marketing-footer.partial.tmpl"),
8 		cfg.StaticPath("html/base.layout.tmpl"),
M prose/public/main.css
+28, -0
 1@@ -324,6 +324,22 @@ figure {
 2   flex: 1;
 3 }
 4 
 5+.layout-aside {
 6+  max-width: 50rem;
 7+}
 8+
 9+.layout-aside aside {
10+  width: 200px;
11+}
12+
13+.layout-aside img {
14+  border-radius: 5px;
15+}
16+
17+#readme {
18+  display: none;
19+}
20+
21 @media only screen and (max-width: 600px) {
22   body {
23     padding: 1rem;
24@@ -332,4 +348,16 @@ figure {
25   header {
26     margin: 0;
27   }
28+
29+  .layout-aside main {
30+    flex-direction: column;
31+  }
32+
33+  aside {
34+    display: none;
35+  }
36+
37+  #readme {
38+    display: block;
39+  }
40 }
M prose/public/prose.css
+0, -30
 1@@ -33,33 +33,3 @@ table {
 2   font-weight: bold;
 3   padding: 0.6rem 0 0 0;
 4 }
 5-
 6-.layout-aside {
 7-  max-width: 50rem;
 8-}
 9-
10-.layout-aside aside {
11-  width: 200px;
12-}
13-
14-.layout-aside img {
15-  border-radius: 5px;
16-}
17-
18-#readme {
19-  display: none;
20-}
21-
22-@media only screen and (max-width: 600px) {
23-  .layout-aside main {
24-    flex-direction: column;
25-  }
26-
27-  #readme {
28-    display: block;
29-  }
30-
31-  aside {
32-    display: none;
33-  }
34-}
M smol.css
+28, -0
 1@@ -324,6 +324,22 @@ figure {
 2   flex: 1;
 3 }
 4 
 5+.layout-aside {
 6+  max-width: 50rem;
 7+}
 8+
 9+.layout-aside aside {
10+  width: 200px;
11+}
12+
13+.layout-aside img {
14+  border-radius: 5px;
15+}
16+
17+#readme {
18+  display: none;
19+}
20+
21 @media only screen and (max-width: 600px) {
22   body {
23     padding: 1rem;
24@@ -332,4 +348,16 @@ figure {
25   header {
26     margin: 0;
27   }
28+
29+  .layout-aside main {
30+    flex-direction: column;
31+  }
32+
33+  aside {
34+    display: none;
35+  }
36+
37+  #readme {
38+    display: block;
39+  }
40 }