- commit
- 881e58f9232a7892d4a16fab42a2e2dd03017dec
- parent
- ecd7c1577bd374c20eceb93c049a2e2af3627a2e
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2025-12-21 11:51
render show as html
Diffstat
| M | audiothek.go | 18 | +++++++++++++++--- |
| M | style.css | 71 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
| A | templates/show.html | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 122 insertions, 13 deletions
diff --git a/audiothek.go b/audiothek.go
@@ -24,7 +24,7 @@ import ( 24 24 25 25 const COUNT = 20 26 2627 -1 var urlPattern = regexp.MustCompile(`^/([0-9]+|urn:ard:show:[a-z0-9]+)\.(rss|m3u)$`)-1 27 var urlPattern = regexp.MustCompile(`^/([0-9]+|urn:ard:show:[a-z0-9]+)(\.rss|\.m3u|\/)$`) 28 28 var origin = "" 29 29 30 30 const QUERY = ` @@ -80,6 +80,7 @@ var tplData embed.FS 80 80 var tplFuncs = template.FuncMap{ 81 81 "reverse": reverse, 82 82 "trim": strings.TrimSpace, -1 83 "date": formatDate, 83 84 "rssDate": rssDate, 84 85 "imgWidth": imgWidth, 85 86 "itunesCategory": itunesCategory, @@ -147,6 +148,14 @@ func reverse(items []Item) iter.Seq[Item] { 147 148 } 148 149 } 149 150 -1 151 func formatDate(s string) (string, error) { -1 152 t, err := time.Parse(time.RFC3339, s) -1 153 if err != nil { -1 154 return "", err -1 155 } -1 156 return t.Format("02.01.2006"), nil -1 157 } -1 158 150 159 func rssDate(s string) (string, error) { 151 160 t, err := time.Parse(time.RFC3339, s) 152 161 if err != nil { @@ -230,12 +239,15 @@ func handle(w http.ResponseWriter, r *http.Request) { 230 239 NextOffset: offset + COUNT, 231 240 } 232 241233 -1 if matches[2] == "rss" {-1 242 if matches[2] == ".rss" { 234 243 w.Header().Set("Content-Type", "text/xml") 235 244 err = tpl.ExecuteTemplate(w, "show.rss", ctx)236 -1 } else if matches[2] == "m3u" {-1 245 } else if matches[2] == ".m3u" { 237 246 w.Header().Set("Content-Type", "text/plain") 238 247 err = tpl.ExecuteTemplate(w, "show.m3u", ctx) -1 248 } else if matches[2] == "/" { -1 249 w.Header().Set("Content-Type", "text/html") -1 250 err = tpl.ExecuteTemplate(w, "show.html", ctx) 239 251 } 240 252 241 253 if err != nil {
diff --git a/style.css b/style.css
@@ -1,6 +1,10 @@
-1 1 * {
-1 2 box-sizing: border-box;
-1 3 }
-1 4
1 5 body {
2 -1 max-inline-size: 40em;
3 -1 padding: 1em;
-1 6 max-inline-size: 50em;
-1 7 padding-inline: 1em;
4 8 margin-block: 0;
5 9 margin-inline: auto;
6 10 background-color: #000e29;
@@ -8,21 +12,68 @@ body {
8 12 font-family: sans-serif;
9 13 line-height: 1.4;
10 14 }
-1 15
11 16 a {
12 17 color: #007aff;
13 18 }
14 -1 pre {
15 -1 font-size: 125%;
16 -1 border-radius: 0.2em;
17 -1 background-color: #243350;
18 -1 padding: 0.5em;
19 -1 overflow: auto;
20 -1 }
21 -1 h2 {
-1 19
-1 20 h2, h3 {
-1 21 line-height: 1.2;
22 22 margin-block: 2em 0.5rem;
23 23 }
-1 24
-1 25 img {
-1 26 max-inline-size: 100%;
-1 27 block-size: auto;
-1 28 }
-1 29
24 30 blockquote {
25 31 margin-inline: 0;
26 32 padding-inline-start: 1em;
27 33 border-inline-start: 0.5em solid #243350;
28 34 }
-1 35
-1 36 pre,
-1 37 .btn {
-1 38 font-family: inherit;
-1 39 font-size: inherit;
-1 40 color: inherit;
-1 41 border: 2px solid #243350;
-1 42 border-radius: 0.2em;
-1 43 padding-inline: 1em;
-1 44 padding-block: 0.5em;
-1 45 }
-1 46
-1 47 pre,
-1 48 .btn:hover {
-1 49 background-color: #243350;
-1 50 }
-1 51 .btn {
-1 52 background: transparent;
-1 53 text-decoration: none;
-1 54 }
-1 55 pre {
-1 56 font-size: 125%;
-1 57 }
-1 58
-1 59 .center {
-1 60 margin-block: 0 4em;
-1 61 text-align: center;
-1 62 }
-1 63
-1 64 .items {
-1 65 padding: 0;
-1 66 }
-1 67 .items li {
-1 68 display: flex;
-1 69 align-items: start;
-1 70 gap: 1em;
-1 71 margin-block: 0 2em;
-1 72 }
-1 73 .items div {
-1 74 flex: 1;
-1 75 }
-1 76 .items h3,
-1 77 .items p {
-1 78 margin-block: 0 0.2em;
-1 79 }
diff --git a/templates/show.html b/templates/show.html
@@ -0,0 +1,46 @@
-1 1 <!DOCTYPE html>
-1 2 <html lang="de">
-1 3 <head>
-1 4 <meta charset="utf-8">
-1 5 <meta name="viewport" content="width=device-width">
-1 6 <title>{{.Show.Title | html}} · Audiothek</title>
-1 7 <link rel="stylesheet" type="text/css" href="/style.css">
-1 8 <link rel="alternate" type="application/rss+xml" href="/{{.Id | html}}.rss">
-1 9 </head>
-1 10 <body>
-1 11 <main>
-1 12 <div class="center">
-1 13 <h2>{{.Show.Title | html}}</h2>
-1 14 <div>
-1 15 {{.Show.PublicationService.Title | html}}
-1 16 {{- if .Show.EditorialCategory.Title}}
-1 17 · {{.Show.EditorialCategory.Title | html}}
-1 18 {{- end}}
-1 19 · <a href="/{{.Id | html}}.rss" rel="alternate">RSS</a>
-1 20 · <a href="/{{.Id | html}}.m3u" rel="alternate">M3U</a>
-1 21 · <a href="{{.Show.SharingUrl | html}}" rel="alternate">Audiothek</a>
-1 22 </div>
-1 23 <p>{{.Show.Synopsis | html}}</p>
-1 24 </div>
-1 25 <ul class="items">
-1 26 {{- range .Show.Items.Nodes}}
-1 27 {{- $audio := index .Audios 0 }}
-1 28 <li>
-1 29 <a href="{{$audio.Url | html}}" tabindex="-1">
-1 30 <img src="{{.Image.Url1X1 | imgWidth 120 | html}}" alt="" width="120" height="120" loading="lazy">
-1 31 </a>
-1 32 <div>
-1 33 <time datetime="{{.PublishDate | html}}">{{.PublishDate | date | html}}</time>
-1 34 <h3><a href="{{$audio.Url | html}}">{{.Title | html}}</a></h3>
-1 35 <p>{{.Summary | html}}…</p>
-1 36 </div>
-1 37 </li>
-1 38 {{- end}}
-1 39 </ul>
-1 40 {{- if .Show.Items.PageInfo.HasNextPage}}
-1 41 <div class="center">
-1 42 <a href="?offset={{.NextOffset | html}}" rel="next" class="btn">Mehr…</a>
-1 43 </div>
-1 44 {{- end}}
-1 45 </main>
-1 46 </body>